home *** CD-ROM | disk | FTP | other *** search
/ OctaMED Sound Studio 1 / OctaMED SoundStudio V1.iso / soundstudio v1 / programmers / pro8player.a < prev    next >
Text File  |  1996-06-18  |  69KB  |  2,546 lines

  1. ;============================================================================
  2. ;    pro8player.a
  3. ;    ~~~~~~~~~~~
  4. ; $VER: pro8player 7.0 (4.2.1996)
  5. ;
  6. ; The music player routine for MMD0/MMD1/MMD2 MED/OctaMED
  7. ; eight channel modules.
  8. ;
  9. ; Copyright © 1995-1996 Teijo Kinnunen and RBF Software.
  10. ;
  11. ; Written by Teijo Kinnunen.
  12. ; Comments/questions/bug reports can be sent to:
  13. ;    Teijo Kinnunen
  14. ;    Oksantie 19
  15. ;    FIN-86300  OULAINEN
  16. ;    FINLAND
  17. ;    email: Teijo.Kinnunen@oulu.fi
  18. ;
  19. ; See OctaMED docs for conditions about using these routines.
  20. ; Comments/questions about distribution and usage conditions
  21. ; should be directed to RBF Software. (Email: rbfsoft@cix.compulink.co.uk)
  22. ;
  23. ;============================================================================
  24.  
  25. ;****** Feature control ******
  26. ;
  27. AUDDEV        EQU 1    ;1 = allocate channels using audio.device
  28. CHECK        EQU 1    ;1 = do range checkings (track, sample in mem etc.)
  29. IFFMOCT        EQU 1    ;1 = play IFF multi-octave samples correctly
  30. HOLD        EQU 1    ;1 = handle hold/decay
  31. PLAYMMD0    EQU 1    ;1 = play old MMD0 modules
  32. FASTMEMPLAY    EQU 1    ;1 = make FastMemPlay available
  33. ;============================================================================
  34.  
  35. ; The MMD structure offsets
  36. mmd_id        EQU    0
  37. mmd_modlen    EQU    4
  38. mmd_songinfo    EQU    8
  39. ; these two for MMD2s only!
  40. mmd_psecnum    EQU    12
  41. mmd_pseq    EQU    14
  42. ;
  43. mmd_blockarr    EQU    16
  44. mmd_smplarr    EQU    24
  45. mmd_expdata    EQU    32
  46. mmd_pstate    EQU    40 ; <0 = play song, 0 = don't play, >0 = play block
  47. mmd_pblock    EQU    42
  48. mmd_pline    EQU    44
  49. mmd_pseqnum    EQU    46
  50. mmd_actplayline    EQU    48
  51. mmd_counter    EQU    50
  52. mmd_songsleft    EQU    51
  53.  
  54. ; Instrument data
  55. inst_repeat    EQU    0
  56. inst_replen    EQU    2
  57. inst_midich    EQU    4
  58. inst_midipreset    EQU    5
  59. inst_svol    EQU    6
  60. inst_strans    EQU    7
  61.  
  62. ; Audio hardware offsets
  63. ac_ptr    EQU    $00
  64. ac_len    EQU    $04
  65. ac_per    EQU    $06
  66. ac_vol    EQU    $08
  67. ac_end    EQU    $0C
  68. ac_rest    EQU    $10
  69. ac_mask    EQU    $14
  70. ac_rhw    EQU    $16
  71. ac_fmp    EQU    $1A
  72.  
  73.         INCLUDE    "medtrkdata.i"
  74.  
  75.         SECTION    "text",CODE
  76.  
  77.     IFNE    FASTMEMPLAY
  78. rpnewv        rts
  79. sdma_fastmem    move.w    intonmsk-DB(a6),d0
  80.         beq.s    rpnewv        ;a RTS
  81.         movem.l    a2/a5/d2,-(sp)
  82.         move.w    d0,d2
  83.         lea    trackdata8-DB+4(a6),a2
  84.         lsr.w    #8,d2
  85.         movea.l    (a2)+,a1
  86.         lsr.b    #1,d2
  87.         bcc.s    2$
  88.         movea.l    trk_fmp(a1),a1
  89.         lea    $DFF000,a0
  90.         bsr.w    _FmpIntHandler
  91. 2$        movea.l    (a2)+,a1
  92.         lsr.b    #1,d2
  93.         bcc.s    3$
  94.         movea.l    trk_fmp(a1),a1
  95.         lea    $DFF000,a0
  96.         bsr.w    _FmpIntHandler
  97. 3$        lsr.b    #1,d2
  98.         bcc.s    4$
  99.         movea.l    (a2),a1
  100.         movea.l    trk_fmp(a1),a1
  101.         lea    $DFF000,a0
  102.         bsr.w    _FmpIntHandler
  103. 4$        movem.l    (sp)+,a2/a5/d2
  104.         bsr    _Wait1line
  105.         move.w    intonmsk-DB(a6),d1
  106.         move.w    d1,INTREQ
  107.         move.w    dmaonmsk-DB(a6),d0
  108.         bset    #15,d0
  109.         move.w    d0,DMACON    ;turn on DMA
  110.         move.w    intonmsk-DB(a6),d1
  111.         bset    #15,d1
  112.         move.w    d1,INTENA    ;enable interrupts
  113.         bra    _Wait1line
  114.  
  115. ;FastMemPlay interrupt handler routine
  116. ;NOTE: audio buffer length must be divisible by 4!
  117. _FmpIntHandler
  118.         move.w    fmp_intmask(a1),$9C(a0)
  119. ; --- See which buffer is in turn
  120.         not.b    fmp_whichbuff(a1)
  121.         beq.s    fih_fillbuff
  122.         movea.l    fmp_bufferptr2(a1),a5
  123.         bra.s    fih_fb2
  124. fih_fillbuff    movea.l    fmp_bufferptr(a1),a5
  125. ; --- Set the audio address for the next buffer
  126. fih_fb2        movea.l    fmp_audioaddr(a1),a0
  127.         move.l    a5,ac_ptr(a0)    ;new sample pointer
  128. ; --- Check whether the channel has something valid to play
  129.         tst.b    fmp_active(a1)
  130.         beq    fih_inactive
  131. ; --- Load remaining buffer size and sample pointer
  132.         moveq    #0,d1
  133.         move.w    fmp_buffsize(a1),d1
  134.         move.l    fmp_currlen(a1),d0
  135.         movea.l    fmp_currptr(a1),a0
  136. ; --- If the remaining sample data entirely fills the buffer,
  137. ; --- do a longword copy
  138.         cmp.l    d1,d0
  139.         bhi.s    fih_fill_whole_l
  140. ; --- Loop. Subtract the remaining sample sz from rem. buffer sz
  141. fih_loop1    sub.w    d0,d1
  142. ; --- Copy the remaining bytes of the sample
  143.         bra.s    2$
  144. 1$        move.b    (a0)+,(a5)+
  145. 2$        dbra    d0,1$
  146. ; --- If no repeat, go and clear the rest of the buffer
  147.         move.l    fmp_repeatptr(a1),d0
  148.         beq.s    fih_norpt
  149. ; --- Load repeat begin pointer to A0
  150.         move.l    d0,a0
  151. ; --- And length in D0
  152.         move.l    fmp_repeatlen(a1),d0
  153. ; --- If buffer was exactly filled, exit
  154.         tst.w    d1
  155.         beq.s    fih_exitintr
  156. ; --- See whether the buffer could be now filled to the end
  157. ; --- (can't use longword copy, because the destination might not be
  158. ; --- aligned due to odd loop length)
  159.         cmp.l    d1,d0
  160.         bhi.s    fih_fill_whole
  161.         bra.s    fih_loop1
  162. fih_exitintr    move.l    d0,fmp_currlen(a1)
  163.         move.l    a0,fmp_currptr(a1)
  164.         rts
  165.  
  166. fih_fill_whole_l
  167. ; --- Subtract copied bytes in advance
  168.         sub.l    d1,d0
  169. ; --- Store the remaining sample length
  170.         move.l    d0,fmp_currlen(a1)
  171.         move.l    a0,d0
  172. ; --- Make sure the source is really aligned (it might not be, if the
  173. ; --- loop was aligned on an even boundary)
  174.         btst    #0,d0
  175.         bne.s    fih_fill_nonalign
  176. ; --- # of longwords
  177.         lsr.w    #2,d1
  178.         subq.w    #1,d1
  179. 1$        move.l    (a0)+,(a5)+
  180.         dbra    d1,1$
  181. ; --- Also store the new source pointer, and exit..
  182.         move.l    a0,fmp_currptr(a1)
  183.         rts
  184. ; --- The same as above, but not a longword copy.
  185. fih_fill_whole    sub.l    d1,d0
  186.         move.l    d0,fmp_currlen(a1)
  187. fih_fill_nonalign
  188.         subq.w    #1,d1
  189. 1$        move.b    (a0)+,(a5)+
  190.         dbra    d1,1$
  191.         move.l    a0,fmp_currptr(a1)
  192.         rts
  193.  
  194. ; --- Turn off this interrupt, and Audio DMA
  195. fih_inactive    move.w    fmp_intmask(a1),d0
  196.         move.w    d0,INTENA
  197.         lsr.w    #7,d0
  198.         move.w    d0,DMACON
  199.         rts
  200. ; --- Fill the rest of the buffer, and cause the channel to go
  201. ; --- inactive when the interrupt occurs the next time
  202. fih_clrloop    clr.b    (a5)+
  203. fih_norpt    dbra    d1,fih_clrloop
  204.         clr.b    fmp_active(a1)
  205.         rts
  206.  
  207.  
  208. _InitFastMemPlayer
  209.         movem.l    a5/a6,-(sp)
  210.         lea    DB,a5
  211.         movea.l    _module8-DB(a5),a0
  212.         movea.l    mmd_songinfo(a0),a0
  213.         tst.b    msng_flags2(a0)
  214.         bmi.w    ifmp_noaudio    ;mixing! don't mess with audio hw..
  215.         lea    fmpstructs,a0
  216.         lea    $DFF0B0,a1
  217.         move.w    _fmp_buffsize8-DB(a5),d0
  218.         move.w    d0,d1
  219.         lsr.w    #1,d1
  220.         move.w    #1<<8,fmp_intmask(a0)
  221.         clr.w    fmp_whichbuff(a0)
  222.         move.l    a1,fmp_audioaddr(a0)
  223.         move.l    #_fmpaudiobuff,fmp_bufferptr(a0)
  224.         move.l    #_fmpaudiobuff+800,fmp_bufferptr2(a0)
  225.         move.w    d0,fmp_buffsize(a0)
  226.         move.w    d1,ac_len(a1)
  227.         lea    fmp_sizeof(a0),a0
  228.         lea    $10(a1),a1
  229.         move.w    #1<<9,fmp_intmask(a0)
  230.         clr.w    fmp_whichbuff(a0)
  231.         move.l    a1,fmp_audioaddr(a0)
  232.         move.l    #_fmpaudiobuff+1600,fmp_bufferptr(a0)
  233.         move.l    #_fmpaudiobuff+2400,fmp_bufferptr2(a0)
  234.         move.w    d0,fmp_buffsize(a0)
  235.         move.w    d1,ac_len(a1)
  236.         lea    fmp_sizeof(a0),a0
  237.         lea    $10(a1),a1
  238.         move.w    #1<<10,fmp_intmask(a0)
  239.         clr.w    fmp_whichbuff(a0)
  240.         move.l    a1,fmp_audioaddr(a0)
  241.         move.l    #_fmpaudiobuff+3200,fmp_bufferptr(a0)
  242.         move.l    #_fmpaudiobuff+4000,fmp_bufferptr2(a0)
  243.         move.w    d0,fmp_buffsize(a0)
  244.         move.w    d1,ac_len(a1)
  245.         movea.l    4.w,a6
  246. ; channel 0 DMA audio is never used in this routine
  247.         ;lea    fmpinterrupt0-DB(a5),a1
  248.         ;moveq    #7,d0
  249.         ;jsr    -$a2(a6)    ;SetIntVector()
  250.         lea    fmpinterrupt1-DB(a5),a1
  251.         moveq    #8,d0
  252.         jsr    -$a2(a6)    ;SetIntVector()
  253.         lea    fmpinterrupt2-DB(a5),a1
  254.         moveq    #9,d0
  255.         jsr    -$a2(a6)    ;SetIntVector()
  256.         lea    fmpinterrupt3-DB(a5),a1
  257.         moveq    #10,d0
  258.         jsr    -$a2(a6)    ;SetIntVector()
  259.         moveq    #1,d0
  260.         move.w    d0,_use_fastmem-DB(a5)
  261. ifmp_noaudio    movem.l    (sp)+,a5/a6
  262.         rts
  263.  
  264. _RemAudioInts:    move.l    a6,-(sp)
  265.         tst.w    _use_fastmem
  266.         beq.s    1$
  267.         move.w    #$780,INTENA    ;switch audio interrupts off
  268.         movea.l    4.w,a6
  269.         ;suba.l    a1,a1
  270.         ;moveq    #7,d0
  271.         ;jsr    -$a2(a6)    ;SetIntVector()
  272.         suba.l    a1,a1
  273.         moveq    #8,d0
  274.         jsr    -$a2(a6)    ;SetIntVector()
  275.         suba.l    a1,a1
  276.         moveq    #9,d0
  277.         jsr    -$a2(a6)    ;SetIntVector()
  278.         suba.l    a1,a1
  279.         moveq    #10,d0
  280.         jsr    -$a2(a6)    ;SetIntVector()
  281.         clr.w    _use_fastmem
  282. 1$        move.l    (sp)+,a6
  283.         rts
  284.     ENDC
  285.  
  286. ;**************************************************************************
  287. ;*
  288. ;*        8 CHANNEL PLAY ROUTINE
  289. ;*
  290. ;**************************************************************************
  291.  
  292. ; This code does the magic 8 channel thing (mixing).
  293. MAGIC_8TRK    MACRO
  294.         move.b    0(a3,d6.w),d3
  295.         add.l    d1,d6
  296.         addx.w    d0,d6
  297.         add.b    0(a4,d7.w),d3
  298.         add.l    d2,d7
  299.         move.b    d3,(a1)+
  300.         addx.w    d0,d7
  301.         ENDM
  302.  
  303. _ChannelO8    clr.w    trk_prevper(a5)
  304.         movea.l    trk_audioaddr(a5),a0
  305.         clr.w    ac_per(a0)
  306. xco8        rts
  307.  
  308. _PlayNote8:    ;d7(w) = trk #, d1 = note #, d3(w) = instr # a3 = addr of instr
  309.         movea.l    mmd_smplarr(a2),a0
  310.         add.w    d3,d3            ;d3 = instr.num << 2
  311.         add.w    d3,d3
  312.         move.l    0(a0,d3.w),d5        ;get address of instrument
  313.     IFNE    CHECK
  314.         beq.s    xco8
  315.     ENDC
  316. inmem8:        add.b    msng_playtransp(a4),d1    ;add play transpose
  317.         add.b    inst_strans(a3),d1    ;and instr. transpose
  318.     IFNE    CHECK
  319.         tst.b    inst_midich(a3)
  320.         bne.s    xco8        ;MIDI
  321.     ENDC
  322.         clr.b    trk_vibroffs(a5)    ;clr vibrato offset
  323.         move.l    d5,a0
  324.         subq.b    #1,d1
  325.     IFNE    CHECK
  326.         tst.w    4(a0)
  327.         bmi.s    xco8        ;Synth
  328.     ENDC
  329. tlwtst08:    tst.b    d1
  330.         bpl.s    notenot2low8
  331.         add.b    #12,d1    ;note was too low, octave up
  332.         bra.s    tlwtst08
  333. notenot2low8:    cmp.b    #62,d1
  334.         ble.s    endpttest8
  335.         sub.b    #12,d1    ;note was too high, octave down
  336. endpttest8:
  337.         moveq    #0,d2
  338.         moveq    #0,d3
  339.         moveq    #6,d4    ;skip (stereo+hdr) offset
  340.         lea    _periodtable+32-DB(a6),a1
  341.         move.b    trk_finetune(a5),d2    ;finetune value
  342.         add.b    d2,d2
  343.         add.b    d2,d2        ;multiply by 4...
  344.         ext.w    d2        ;extend
  345.         movea.l    0(a1,d2.w),a1    ;period table address
  346.         move.w    4(a0),d0    ;(Instr hdr in a0)
  347.         btst    #5,d0
  348.         beq.s    gid_nostereo
  349.         move.b    d7,d5
  350.         and.b    #3,d5
  351.         beq.s    gid_nostereo    ;ch 0/4 = play left (norm.)
  352.         cmp.b    #3,d5
  353.         beq.s    gid_nostereo    ;also for ch 3/7
  354.         add.l    (a0),d4        ;play right channel
  355. gid_nostereo
  356.     IFNE    IFFMOCT
  357.         and.w    #$F,d0
  358.         bne.s    gid_notnormal    ;note # in d1 (0 - ...)
  359.     ENDC
  360. gid_cont_ext    move.l    a1,trk_periodtbl(a5)
  361.         add.b    d1,d1
  362.         move.w    0(a1,d1.w),d5 ;put period to d5
  363.         move.l    a0,d0
  364.         move.l    (a0),d1        ;length
  365.         add.l    d4,d0        ;skip hdr and stereo
  366.         add.l    d0,d1        ;sample end pointer
  367.         move.w    inst_repeat(a3),d2
  368.         move.w    inst_replen(a3),d3
  369.     IFNE    IFFMOCT
  370.         bra    gid_setrept
  371. gid_addtable    dc.b    0,6,12,18,24,30
  372. gid_divtable    dc.b    31,7,3,15,63,127
  373. gid_notnormal    cmp.w    #7,d0
  374.         blt.s    gid_not_ext
  375.         suba.w    #48,a1
  376.         bra.s    gid_cont_ext
  377. gid_not_ext    move.l    d7,-(sp)
  378.         moveq    #0,d7
  379.         move.w    d1,d7
  380.         divu    #12,d7    ;octave #
  381.         move.l    d7,d5
  382.         cmp.w    #6,d7    ;if oct > 5, oct = 5
  383.         blt.s    nohioct
  384.         moveq    #5,d7
  385. nohioct        swap    d5    ;note number in this oct (0-11) is in d5
  386.         move.l    (a0),d1
  387.         cmp.w    #6,d0
  388.         ble.s    nounrecit
  389.         moveq    #6,d0
  390. nounrecit    add.b    gid_addtable-1(pc,d0.w),d7
  391.         move.b    gid_divtable-1(pc,d0.w),d0
  392.         divu    d0,d1    ;get length of the highest octave
  393.         swap    d1
  394.         clr.w    d1
  395.         swap    d1
  396.         move.l    d1,d0        ;d0 and d1 = length of the 1st oct
  397.         move.w    inst_repeat(a3),d2
  398.         move.w    inst_replen(a3),d3
  399.         moveq    #0,d6
  400.         move.b    shiftcnt(pc,d7.w),d6
  401.         lsl.w    d6,d2
  402.         lsl.w    d6,d3
  403.         lsl.w    d6,d1
  404.         move.b    mullencnt(pc,d7.w),d6
  405.         mulu    d6,d0        ;offset of this oct from 1st oct
  406.         add.l    a0,d0        ;add base address to offset
  407.         add.l    d4,d0        ;skip header + stereo
  408.         add.l    d0,d1
  409.         move.l    a1,trk_periodtbl(a5)
  410.         add.b    octstart(pc,d7.w),d5
  411.         add.b    d5,d5
  412.         move.w    0(a1,d5.w),d5
  413.         move.l    (sp)+,d7
  414.         bra.s    gid_setrept
  415. shiftcnt:    dc.b    4,3,2,1,1,0,2,2,1,1,0,0,1,1,0,0,0,0
  416.         dc.b    3,3,2,2,1,0,5,4,3,2,1,0,6,5,4,3,2,1
  417. mullencnt:    dc.b    15,7,3,1,1,0,3,3,1,1,0,0,1,1,0,0,0,0
  418.         dc.b    7,7,3,3,1,0,31,15,7,3,1,0,63,31,15,7,3,1
  419. octstart:    dc.b    12,12,12,12,24,24,0,12,12,24,24,36,0,12,12,24,36,36
  420.         dc.b    0,12,12,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12
  421.     ENDC
  422. gid_setrept    add.l    d2,d2
  423.         add.l    d0,d2        ;rep. start pointer
  424.         cmp.w    #1,d3
  425.         bhi.s    gid_noreplen2
  426.         moveq    #0,d3        ;no repeat
  427.         bra.s    gid_cont
  428. gid_noreplen2    add.l    d3,d3
  429.         add.l    d2,d3        ;rep. end pointer
  430.  
  431. gid_cont    moveq    #0,d4
  432.         move.w    trk_soffset(a5),d4
  433.         add.l    d4,d0
  434.         cmp.l    d0,d1
  435.         bhi.s    pn_nooffsovf8
  436.         sub.l    d4,d0
  437. pn_nooffsovf8    movea.l    trk_audioaddr(a5),a1 ;base of this channel's regs
  438.         move.l    d0,(a1)        ;put it in ac_ptr
  439.         moveq    #0,d4
  440.         move.b    trk_previnstr(a5),d4
  441.         lea    flags-DB(a6),a0
  442.         btst    #0,0(a0,d4.w)        ;test flags.SSFLG_LOOP
  443.         bhi.s    repeat8
  444.  
  445.         tst.b    trk_split(a5)
  446.         beq.s    pn8_nosplit0
  447.         clr.l    ac_rest(a1)
  448.         subq.l    #1,d1
  449.         move.l    d1,ac_end(a1)
  450.         bra.s    retsn18
  451.  
  452. pn8_nosplit0    sub.l    d0,d1
  453.         lsr.l    #1,d1
  454.         move.w    d1,ac_len(a1)
  455.         tst.w    _use_fastmem-DB(a6)
  456.         bne.s    1$
  457.         move.l    #_chipzero,ac_rest(a1)
  458.         move.w    #1,ac_end(a1)
  459.         bra.s    retsn18
  460. 1$        clr.l    ac_rest(a1)
  461.         bra.s    retsn18
  462.  
  463. repeat8:    tst.b    trk_split(a5)
  464.         bne.s    pn8_split1
  465.         move.l    d3,d1
  466.         sub.l    d0,d1
  467.         lsr.l    #1,d1
  468.         move.w    d1,ac_len(a1)
  469.         move.l    d2,ac_rest(a1)    ;remember rep. start
  470.         sub.l    d2,d3
  471.         lsr.l    #1,d3
  472.         move.w    d3,ac_end(a1)    ;remember rep. length
  473.         bra.s    retsn18
  474.  
  475. pn8_split1    move.l    d2,ac_rest(a1)
  476.         move.l    d3,ac_end(a1)
  477. retsn18:    move.w    d5,ac_per(a1)    ;getinsdata puts period to d5
  478.         move.w    d5,trk_prevper(a5)
  479. retsn28:    rts
  480.  
  481. _IntHandler8:    movem.l    d2-d7/a2-a4,-(sp)
  482.         lea    DB,a6
  483.         lea    trksplit-DB(a6),a2
  484.         move.w    currchsize2-DB(a6),d4
  485. ; ================ 8 channel handling (buffer swap) ======
  486.         move.w    #1600,d0
  487.         not.b    whichbuff-DB(a6)    ;swap buffer
  488.         bne.s    usebuff1
  489.         tst.b    (a2)+
  490.         beq.s    tnspl0
  491.         move.l    a1,$a0(a0)
  492.         move.w    d4,$a4(a0)
  493. tnspl0        lea    1600(a1),a5
  494.         tst.b    (a2)+
  495.         beq.s    tnspl1
  496.         move.l    a5,$b0(a0)
  497.         move.w    d4,$b4(a0)
  498. tnspl1        adda.w    d0,a5
  499.         tst.b    (a2)+
  500.         beq.s    tnspl2
  501.         move.l    a5,$c0(a0)
  502.         move.w    d4,$c4(a0)
  503. tnspl2        adda.w    d0,a5
  504.         tst.b    (a2)
  505.         beq.s    buffset
  506.         move.l    a5,$d0(a0)
  507.         move.w    d4,$d4(a0)
  508.         bra.s    buffset
  509. usebuff1    lea    800(a1),a1
  510.         tst.b    (a2)+
  511.         beq.s    tnspl0b
  512.         move.l    a1,$a0(a0)
  513.         move.w    d4,$a4(a0)
  514. tnspl0b        lea    1600(a1),a5
  515.         tst.b    (a2)+
  516.         beq.s    tnspl1b
  517.         move.l    a5,$b0(a0)
  518.         move.w    d4,$b4(a0)
  519. tnspl1b        adda.w    d0,a5
  520.         tst.b    (a2)+
  521.         beq.s    tnspl2b
  522.         move.l    a5,$c0(a0)
  523.         move.w    d4,$c4(a0)
  524. tnspl2b        tst.b    (a2)
  525.         beq.s    buffset
  526.         adda.w    d0,a5
  527.         move.l    a5,$d0(a0)
  528.         move.w    d4,$d4(a0)
  529. buffset        move.w    #1<<7,$9c(a0)
  530.         lea    tmpvol-DB(a6),a2
  531.         move.b    (a2)+,$a9(a0)
  532.         move.b    (a2)+,$b9(a0)
  533.         move.b    (a2)+,$c9(a0)
  534.         move.b    (a2),$d9(a0)
  535.         tst.b    _hq-DB(a6)
  536.         beq.s    nohq
  537.         move.l    #2031616,d3    ;124 * 16384
  538.         bra.s    startfillb
  539. nohq        move.l    #3719168,d3    ;227 * 16384
  540. ; ============== fill buffers ============
  541. startfillb    moveq    #0,d4        ;mask for DMA
  542.         clr.w    intonmsk-DB(a6)
  543.         lea    track0hw-DB(a6),a2
  544.         tst.b    trksplit-DB(a6)
  545.         bne.s    tspl0c
  546.         bsr.w    pushregs
  547.         bra.s    tnspl0c
  548. tspl0c        bsr.s    fillbuf
  549.         movea.l    a5,a1
  550. tnspl0c        lea    track1hw-DB(a6),a2
  551.         tst.b    trksplit+1-DB(a6)
  552.         bne.s    tspl1c
  553.         bsr.w    pushregs
  554.         bra.s    tnspl1c
  555. tspl1c        bsr.s    fillbuf
  556.         movea.l    a5,a1
  557. tnspl1c        lea    track2hw-DB(a6),a2
  558.         tst.b    trksplit+2-DB(a6)
  559.         bne.s    tspl2c
  560.         bsr.w    pushregs
  561.         bra.s    tnspl2c
  562. tspl2c        bsr.s    fillbuf
  563.         movea.l    a5,a1
  564. tnspl2c        lea    track3hw-DB(a6),a2
  565.         tst.b    trksplit+3-DB(a6)
  566.         bne.s    tspl3c
  567.         bsr.w    pushregs
  568.         bra.w    do_play8
  569. tspl3c        bsr.s    fillbuf
  570.         bra.w    do_play8
  571. ; =========================================================
  572. ;calculate channel A period
  573. fillbuf:    move.l    d3,d7
  574.         move.w    ac_per(a2),d6
  575.         beq.s    setpzero0
  576.         move.l    d7,d2
  577.         divu     d6,d2
  578.         moveq    #0,d1
  579.         move.w    d2,d1
  580.         add.l    d1,d1
  581.         add.l    d1,d1
  582. ;get channel A addresses
  583.         move.l    ac_end(a2),a5
  584.         move.l    (a2),d0
  585.         beq.s    setpzero0
  586. chA_dfnd    move.l    d0,a3    ;a3 = start address, a5 = end address
  587. ;calc bytes before end
  588.         mulu    currchsize-DB(a6),d2
  589.         clr.w    d2
  590.         swap    d2
  591. ; d2 = # of bytes/fill
  592.         add.l    a3,d2    ;d2 = end position after this fill
  593.         sub.l    a5,d2    ;subtract sample end
  594.         bmi.s    norestart0
  595.         move.l    ac_rest(a2),d0
  596.         beq.s    rst0end
  597.         move.l    d0,(a2)
  598.         move.l    d0,a3
  599.         bra.s    norestart0
  600. rst0end        clr.l    (a2)
  601. setpzero0    lea    zerodata-DB(a6),a3
  602.         moveq    #0,d1
  603. norestart0
  604. ;channel B period
  605.         move.w    SIZE4TRKHW+ac_per(a2),d6
  606.         beq.s    setpzero0b
  607.         divu    d6,d7
  608.         moveq    #0,d2
  609.         move.w    d7,d2
  610.         add.l    d2,d2
  611.         add.l    d2,d2
  612. ;channel B addresses
  613.         move.l    SIZE4TRKHW+ac_end(a2),a5
  614.         move.l    SIZE4TRKHW(a2),d0
  615.         beq.s    setpzero0b
  616.         move.l    d0,a4
  617.         mulu    currchsize-DB(a6),d7
  618.         clr.w    d7
  619.         swap    d7
  620.         add.l    a4,d7
  621.         sub.l    a5,d7
  622.         bmi.s    norestart0b
  623.         move.l    SIZE4TRKHW+ac_rest(a2),d0
  624.         beq.s    rst0endb
  625.         move.l    d0,SIZE4TRKHW(a2)
  626.         move.l    d0,a4
  627.         bra.s    norestart0b
  628. rst0endb    clr.l    SIZE4TRKHW(a2)
  629. setpzero0b    lea    zerodata-DB(a6),a4
  630.         moveq    #0,d2
  631. norestart0b    moveq    #0,d6
  632.         moveq    #0,d7
  633.         moveq    #0,d0
  634.         move.w    d3,-(sp)
  635.         swap    d1
  636.         swap    d2
  637.         lea    1600(a1),a5    ;get addr. of next buffer
  638.         tst.b    _hq-DB(a6)
  639.         bne.w    magic_hq
  640.         move.w    currchszcnt-DB(a6),d5
  641. do8trkmagic
  642.         MAGIC_8TRK    ;20 times..
  643.         MAGIC_8TRK
  644.         MAGIC_8TRK
  645.         MAGIC_8TRK
  646.         MAGIC_8TRK
  647.         MAGIC_8TRK
  648.         MAGIC_8TRK
  649.         MAGIC_8TRK
  650.         MAGIC_8TRK
  651.         MAGIC_8TRK
  652.         MAGIC_8TRK
  653.         MAGIC_8TRK
  654.         MAGIC_8TRK
  655.         MAGIC_8TRK
  656.         MAGIC_8TRK
  657.         MAGIC_8TRK
  658.         MAGIC_8TRK
  659.         MAGIC_8TRK
  660.         MAGIC_8TRK
  661.         MAGIC_8TRK
  662.  
  663.         dbf    d5,do8trkmagic    ;do until cnt zero
  664. end8trkmagic    swap    d6
  665.         swap    d7
  666.         clr.w    d6
  667.         clr.w    d7
  668.         swap    d6
  669.         swap    d7
  670.         add.l    d6,(a2)
  671.         add.l    d7,SIZE4TRKHW(a2)
  672.         move.w    (sp)+,d3
  673.         rts
  674. ; The following code is executed only in HQ-mode
  675. magic_hq    move.w    currchsize2-DB(a6),d5
  676.         lsr.w    #1,d5
  677.         subq.w    #1,d5
  678. dohq8trkmagic    ;this runs quite efficiently in a cache
  679.         MAGIC_8TRK
  680.         MAGIC_8TRK
  681.         MAGIC_8TRK
  682.         MAGIC_8TRK
  683.         dbf    d5,dohq8trkmagic
  684.         bra.s    end8trkmagic
  685.  
  686. _Wait1line:    move.l    d0,-(sp)
  687.         moveq    #$79,d0
  688. wl0:        move.b    $dff007,d1
  689. wl1:        cmp.b    $dff007,d1
  690.         beq.s    wl1
  691.         dbf    d0,wl0
  692.         move.l    (sp)+,d0
  693.         rts
  694. ; ========== this channel is not splitted
  695. pushregs    move.l    ac_rhw(a2),a3        ;address of real hardware
  696.         tst.w    ac_per(a2)
  697.         beq.s    pregs_stop
  698.         move.w    ac_per(a2),ac_per(a3)    ;push new period
  699.         move.l    (a2),d0    ;ac_ptr
  700.         beq.s    pregs_nonewp
  701.         move.w    ac_mask(a2),d1
  702.         move.w    d1,$96(a0)    ;stop DMA of curr. channel
  703.         or.w    d1,d4
  704.         clr.l    (a2)
  705.     IFNE    FASTMEMPLAY
  706.         tst.w    _use_fastmem-DB(a6)
  707.         bne.s    pregs_fmp
  708.     ENDC
  709.         move.l    d0,(a3)+    ;to real ac_ptr
  710.         move.w    ac_len(a2),(a3)    ;push ac_len
  711. pregs_nonewp    lea    800(a1),a1    ;next buffer
  712.         rts
  713. pregs_stop    move.w    ac_mask(a2),d1
  714.         move.w    d1,$96(a0)
  715.         bra.s    pregs_nonewp
  716.     IFNE    FASTMEMPLAY
  717. pregs_fmp    move.l    a0,-(sp)
  718.         movea.l    ac_fmp(a2),a0
  719.         move.w    fmp_intmask(a0),d1
  720.         move.w    d1,INTENA
  721.         or.w    d1,intonmsk-DB(a6)
  722.         st    fmp_active(a0)
  723.         move.l    d0,(a0)+    ;fmp_currptr
  724.         moveq    #0,d0
  725.         move.w    ac_len(a2),d0
  726.         add.l    d0,d0
  727.         move.l    d0,(a0)+    ;fmp_currlen
  728.         move.l    ac_rest(a2),(a0)+    ;fmp_rept
  729.         move.l    ac_end(a2),d0
  730.         sub.l    ac_rest(a2),d0
  731.         move.l    d0,(a0)        ;fmp_repeatlen
  732.         move.l    (sp)+,a0
  733.         bra.s    pregs_nonewp
  734.     ENDC
  735. ; ========== should we start DMA of non-splitted channels?
  736. do_play8_fm    move.w    d4,dmaonmsk-DB(a6)
  737.         bsr.w    sdma_fastmem
  738.         bra.s    do_play8_b
  739.  
  740. do_play8    tst.w    d4
  741.         beq.s    do_play8_b    ;no.
  742.         tst.w    _use_fastmem-DB(a6)
  743.         bne.s    do_play8_fm
  744.         bsr.w    _Wait1line
  745.         bset    #15,d4
  746.         move.w    d4,$96(a0)
  747.         bsr.w    _Wait1line
  748.         lsr.b    #1,d4
  749.         bcc.s    plr_nos8dma0
  750.         move.l    track0hw+ac_rest-DB(a6),$a0(a0)
  751.         move.w    track0hw+ac_end-DB(a6),$a4(a0)
  752. plr_nos8dma0    lsr.b    #1,d4
  753.         bcc.s    plr_nos8dma1
  754.         move.l    track1hw+ac_rest-DB(a6),$b0(a0)
  755.         move.w    track1hw+ac_end-DB(a6),$b4(a0)
  756. plr_nos8dma1    lsr.b    #1,d4
  757.         bcc.s    plr_nos8dma2
  758.         move.l    track2hw+ac_rest-DB(a6),$c0(a0)
  759.         move.w    track2hw+ac_end-DB(a6),$c4(a0)
  760. plr_nos8dma2    lsr.b    #1,d4
  761.         bcc.s    do_play8_b
  762.         move.l    track3hw+ac_rest-DB(a6),$d0(a0)
  763.         move.w    track3hw+ac_end-DB(a6),$d4(a0)
  764. ; ========== player starts here...
  765. do_play8_b    movea.l    _module8-DB(a6),a2
  766.         move.l    a2,d0
  767.         beq.w    plr_exit
  768.         move.l    mmd_songinfo(a2),a4
  769.         moveq    #0,d3
  770.         lea    mmd_counter(a2),a0
  771.         move.b    (a0),d3
  772.         addq.b    #1,d3
  773.         cmp.b    msng_tempo2(a4),d3
  774.         bge.s    plr_pnewnote8    ;play new note
  775.         move.b    d3,(a0)
  776.         bra.w    nonewnote    ;do just fx
  777. ; --- new note!! first get address of current block
  778. plr_pnewnote8:    clr.b    (a0)
  779.         tst.w    blkdelay-DB(a6)
  780.         beq.s    plr_noblkdelay8
  781.         subq.w    #1,blkdelay-DB(a6)
  782.         bne.w    nonewnote
  783. ; -------- GET ADDRESS OF NOTE DATA --------------------------------------
  784. plr_noblkdelay8    move.w    mmd_pblock(a2),d0
  785.         bsr.w    GetNoteDataAddr
  786.         moveq    #0,d7        ;number of track
  787.         moveq    #0,d4
  788.     IFNE    PLAYMMD0
  789.         cmp.b    #'1',3(a2)
  790.         sge    d5        ;d5 set -> >= MMD1
  791.     ENDC
  792.         lea    trackdata8-DB(a6),a1
  793. ; -------- TRACK LOOP (FOR EACH TRACK) -----------------------------------
  794. plr_loop0:    movea.l    (a1)+,a5    ;get address of this track's struct
  795. ; ---------------- get the note numbers
  796.         moveq    #0,d3
  797.     IFNE    PLAYMMD0
  798.         tst.b    d5
  799.         bne.s    plr_mmd1_1
  800.         move.b    (a3)+,d0
  801.         move.b    (a3),d3
  802.         addq.l    #2,a3
  803.         lsr.b    #4,d3
  804.         bclr    #7,d0
  805.         beq.s    plr_bseti4
  806.         bset    #4,d3
  807. plr_bseti4    bclr    #6,d0
  808.         beq.s    plr_bseti5
  809.         bset    #5,d3
  810. plr_bseti5    move.b    d0,trk_currnote(a5)
  811.         beq.s    plr_nngok
  812.         move.b    d0,(a5)
  813.         bra.s    plr_nngok
  814. plr_mmd1_1
  815.     ENDC
  816.         move.b    (a3)+,d0    ;get the number of this note
  817.         bpl.s    plr_nothinote
  818.         moveq    #0,d0
  819. plr_nothinote    move.b    d0,trk_currnote(a5)
  820.         beq.s    plr_nosetprevn
  821.         move.b    d0,(a5)
  822. plr_nosetprevn    move.b    (a3),d3        ;instrument number
  823.         addq.l    #3,a3        ;adv. to next track
  824. ; ---------------- check if there's an instrument number
  825. plr_nngok    clr.b    trk_fxtype(a5)
  826.         and.w    #$3F,d3
  827.         beq.s    noinstnum
  828. ; ---------------- finally, save the number
  829.         subq.b    #1,d3
  830.         move.b    d3,trk_previnstr(a5) ;remember instr. number!
  831. ; ---------------- get the pointer of data's of this sample in Song-struct
  832.         move.w    d3,d1
  833.         asl.w    #3,d3
  834.         lea    0(a4,d3.w),a0    ;a0 contains now address of it
  835.         move.l    a0,trk_previnstra(a5)
  836.         move.b    inst_strans(a0),trk_stransp(a5)
  837. ; ---------------- set volume to 64
  838.         movea.l    trk_audioaddr(a5),a0
  839.         movea.l    ac_vol(a0),a0    ;ptr to volume hardware register
  840.         moveq    #64,d0
  841.         move.b    d0,(a0)
  842.         move.b    d0,trk_prevvol(a5)
  843. ; ---------------- remember some values of this instrument
  844.         lea    holdvals-DB(a6),a0
  845.         adda.w    d1,a0
  846.     IFNE    HOLD
  847.         move.b    (a0),trk_inithold(a5)        ;hold
  848.     ENDC
  849.         move.b    63(a0),trk_finetune(a5)        ;finetune
  850. ; ---------------- remember transpose
  851.         clr.w    trk_soffset(a5)        ;sample offset
  852.         clr.b    trk_miscflags(a5)    ;misc.
  853. noinstnum    addq.w    #1,d7
  854.         cmp.w    numtracks-DB(a6),d7
  855.         blt    plr_loop0
  856.         bsr.w    DoPreFXLoop
  857. ; -------- NOTE PLAYING LOOP ---------------------------------------------
  858.         moveq    #0,d7
  859.         lea    trackdata8-DB(a6),a1
  860. plr_loop2    movea.l    (a1)+,a5
  861.         tst.b    trk_fxtype(a5)
  862.         bne.s    plr_loop2_end
  863.         move.b    trk_currnote(a5),d1
  864.         beq.s    plr_loop2_end
  865. ; ---------------- play
  866.         move.l    a1,-(sp)
  867.         ext.w    d1
  868.         moveq    #0,d3
  869.         move.b    trk_previnstr(a5),d3    ;instr #
  870.         movea.l    trk_previnstra(a5),a3    ;instr data address
  871.         move.b    trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  872.         bne.s    plr_nohold0        ;not 0 -> OK
  873.         st    trk_noteoffcnt(a5)    ;0 -> hold = 0xff (-1)
  874. ; ---------------- and finally:
  875. plr_nohold0    bsr    _PlayNote8        ;play it
  876.         move.l    (sp)+,a1
  877. plr_loop2_end    addq.w    #1,d7
  878.         cmp.w    numtracks-DB(a6),d7
  879.         blt.s    plr_loop2
  880. ; -------- THE REST... ---------------------------------------------------
  881.         bsr.s    AdvSngPtr
  882. nonewnote    bsr.w    DoFX
  883. plr_exit    movem.l    (sp)+,d2-d7/a2-a4
  884.         moveq    #1,d0
  885.         rts
  886.  
  887. AdvSngPtr    move.l    mmd_pblock(a2),fxplineblk-DB(a6) ;store pline/block for fx
  888.         move.w    nextblockline-DB(a6),d1
  889.         beq.s    plr_advlinenum
  890.         clr.w    nextblockline-DB(a6)
  891.         subq.w    #1,d1
  892.         bra.s    plr_linenumset
  893. plr_advlinenum    move.w    mmd_pline(a2),d1    ;get current line #
  894.         addq.w    #1,d1            ;advance line number
  895. plr_linenumset    cmp.w    numlines-DB(a6),d1     ;advance block?
  896.         bhi.s    plr_chgblock        ;yes.
  897.         tst.b    nextblock-DB(a6)    ;command F00/1Dxx?
  898.         beq.w    plr_nochgblock        ;no, don't change block
  899. ; -------- CHANGE BLOCK? -------------------------------------------------
  900. plr_chgblock    tst.b    nxtnoclrln-DB(a6)
  901.         bne.s    plr_noclrln
  902.         moveq    #0,d1            ;clear line number
  903. plr_noclrln    tst.w    mmd_pstate(a2)        ;play block or play song
  904.         bpl.w    plr_nonewseq        ;play block only...
  905.         cmp.b    #'2',3(a2)        ;MMD2?
  906.         bcs.s    plr_noMMD2_0
  907. ; ********* BELOW CODE FOR MMD2 ONLY ************************************
  908. ; -------- CHANGE SEQUENCE -----------------------------------------------
  909. plr_skipseq    move.w    mmd_pseq(a2),d0        ;actually stored as << 2
  910.         movea.l    msng_pseqs(a4),a1    ;ptr to playseqs
  911.         movea.l    0(a1,d0.w),a0        ;a0 = ptr to curr PlaySeq
  912.         move.w    mmd_pseqnum(a2),d0    ;get play sequence number
  913.         tst.b    nextblock-DB(a6)
  914.         bmi.s    plr_noadvseq        ;Bxx sets nextblock to -1
  915.         addq.w    #1,d0            ;advance sequence number
  916. plr_noadvseq    cmp.w    40(a0),d0        ;is this the highest seq number??
  917.         blt.s    plr_notagain        ;no.
  918. ; -------- CHANGE SECTION ------------------------------------------------
  919.         move.w    mmd_psecnum(a2),d0    ;get section number
  920.         addq.w    #1,d0            ;increase..
  921.         cmp.w    msng_songlen(a4),d0    ;highest section?
  922.         blt.s    plr_nohisec
  923.         moveq    #0,d0            ;yes.
  924. plr_nohisec    move.w    d0,mmd_psecnum(a2)    ;push back.
  925.         add.w    d0,d0
  926.         movea.l    msng_sections(a4),a0    ;section table
  927.         move.w    0(a0,d0.w),d0        ;new playseqlist number
  928.         add.w    d0,d0
  929.         add.w    d0,d0
  930.         move.w    d0,mmd_pseq(a2)
  931.         movea.l    0(a1,d0.w),a0        ;a0 = ptr to new PlaySeq
  932.         moveq    #0,d0            ;playseq OFFSET = 0
  933. ; -------- FETCH BLOCK NUMBER FROM SEQUENCE ------------------------------
  934. plr_notagain    move.w    d0,mmd_pseqnum(a2)    ;remember new playseq pos
  935.         add.w    d0,d0
  936.         move.w    42(a0,d0.w),d0        ;get number of the block
  937.         bpl.s    plr_changeblk    ;neg. values for future expansion
  938.         bra.s    plr_skipseq    ;(skip them)
  939. ; ********* BELOW CODE FOR MMD0/MMD1 ONLY *******************************
  940. plr_noMMD2_0    move.w    mmd_pseqnum(a2),d0    ;get play sequence number
  941.         tst.b    nextblock-DB(a6)
  942.         bmi.s    plr_noadvseq_b        ;Bxx sets nextblock to -1
  943.         addq.w    #1,d0            ;advance sequence number
  944. plr_noadvseq_b    cmp.w    msng_songlen(a4),d0    ;is this the highest seq number??
  945.         blt.s    plr_notagain_b        ;no.
  946.         moveq    #0,d0            ;yes: restart song
  947. plr_notagain_b    move.b    d0,mmd_pseqnum+1(a2)    ;remember new playseq-#
  948.         lea    msng_playseq(a4),a0    ;offset of sequence table
  949.         move.b    0(a0,d0.w),d0        ;get number of the block
  950. ; ********* BELOW CODE FOR BOTH FORMATS *********************************
  951. plr_changeblk
  952.     IFNE    CHECK
  953.         cmp.w    msng_numblocks(a4),d0    ;beyond last block??
  954.         blt.s    plr_nolstblk        ;no..
  955.         moveq    #0,d0            ;play block 0
  956.     ENDC
  957. plr_nolstblk    move.w    d0,mmd_pblock(a2)    ;store block number
  958. plr_nonewseq    clr.w    nextblock-DB(a6)     ;clear this if F00 set it
  959. ; ------------------------------------------------------------------------
  960. plr_nochgblock    move.w    d1,mmd_pline(a2)    ;set new line number
  961.  
  962.     IFNE    HOLD
  963.         lea    trackdata8-DB(a6),a5
  964.         move.w    mmd_pblock(a2),d0    ;pblock
  965.         bsr.w    GetBlockAddr
  966.         move.w    mmd_pline(a2),d0    ;play line
  967.         move.b    msng_tempo2(a4),d3    ;interrupts/note
  968.     IFNE    PLAYMMD0
  969.         cmp.b    #'1',3(a2)
  970.         bge.s    plr_mmd1_2
  971.         move.b    (a0),d7            ;# of tracks
  972.         move.w    d0,d1
  973.         add.w    d0,d0    ;d0 * 2
  974.         add.w    d1,d0    ;+ d0 = d0 * 3
  975.         mulu    d7,d0
  976.         lea    2(a0,d0.w),a3
  977.         subq.b    #1,d7
  978. plr_chkholdb    movea.l    (a5)+,a1        ;track data
  979.         tst.b    trk_noteoffcnt(a1)    ;hold??
  980.         bmi.s    plr_holdendb        ;no.
  981.         move.b    (a3),d1            ;get the 1st byte..
  982.         bne.s    plr_hold1b
  983.         move.b    1(a3),d1
  984.         and.b    #$f0,d1
  985.         beq.s    plr_holdendb        ;don't hold
  986.         bra.s    plr_hold2b
  987. plr_hold1b    and.b    #$3f,d1            ;note??
  988.         beq.s    plr_hold2b        ;no, cont hold..
  989.         move.b    1(a3),d1
  990.         and.b    #$0f,d1            ;get cmd
  991.         subq.b    #3,d1            ;is there command 3 (slide)
  992.         bne.s    plr_holdendb        ;no -> end holding
  993. plr_hold2b    add.b    d3,trk_noteoffcnt(a1)    ;continue holding...
  994. plr_holdendb    addq.l    #3,a3        ;next note
  995.         dbf    d7,plr_chkholdb
  996.         rts
  997. plr_mmd1_2
  998.     ENDC
  999.         move.w    (a0),d7        ;# of tracks
  1000.         add.w    d0,d0
  1001.         add.w    d0,d0        ;d0 = d0 * 4
  1002.         mulu    d7,d0
  1003.         lea    8(a0,d0.l),a3
  1004.         subq.b    #1,d7
  1005. plr_chkhold    movea.l    (a5)+,a1        ;track data
  1006.         tst.b    trk_noteoffcnt(a1)    ;hold??
  1007.         bmi.s    plr_holdend        ;no.
  1008.         move.b    (a3),d1            ;get the 1st byte..
  1009.         bne.s    plr_hold1
  1010.         move.b    1(a3),d0
  1011.         and.b    #$3F,d0
  1012.         beq.s    plr_holdend        ;don't hold
  1013.         bra.s    plr_hold2
  1014. plr_hold1    and.b    #$7f,d1            ;note??
  1015.         beq.s    plr_hold2        ;no, cont hold..
  1016.         move.b    2(a3),d1
  1017.         subq.b    #3,d1            ;is there command 3 (slide)
  1018.         bne.s    plr_holdend        ;no -> end holding
  1019. plr_hold2    add.b    d3,trk_noteoffcnt(a1)    ;continue holding...
  1020. plr_holdend    addq.l    #4,a3        ;next note
  1021.         dbf    d7,plr_chkhold
  1022.     ENDC
  1023.         rts
  1024.  
  1025. ; *******************************************************************
  1026. ; DoPreFXLoop:    Loop and call DoPreFX
  1027. ; *******************************************************************
  1028. DoPreFXLoop:
  1029. ; -------- PRE-FX COMMAND HANDLING LOOP ----------------------------------
  1030.         moveq    #0,d5    ;command page count
  1031. plr_loop1    move.w    mmd_pblock(a2),d0
  1032.         bsr.w    GetBlockAddr
  1033.         move.w    d5,d1
  1034.         move.w    mmd_pline(a2),d2
  1035.         bsr.w    GetCmdPointer
  1036.         movea.l    a0,a3
  1037.         moveq    #0,d7    ;clear track count
  1038.         lea    trackdata8-DB(a6),a1
  1039. plr_loop1_1    movea.l    (a1)+,a5
  1040.         move.b    (a3),d0            ;command #
  1041.         beq.s    plr_loop1_end
  1042.         moveq    #0,d4
  1043.         move.b    1(a3),d4        ;data byte
  1044.     IFNE    PLAYMMD0
  1045.         cmp.b    #3,d6            ;if adv == 3 -> MMD0
  1046.         bne.s    doprefx_mmd12mask
  1047.         and.w    #$0F,d0
  1048.         bra.s    doprefx_mmd0maskd
  1049. doprefx_mmd12mask
  1050.     ENDC
  1051.         and.w    #$1F,d0
  1052. doprefx_mmd0maskd
  1053.         bsr.s    DoPreFX
  1054.         or.b    d0,trk_fxtype(a5)
  1055. plr_loop1_end    adda.w    d6,a3            ;next track...
  1056.         addq.w    #1,d7
  1057.         cmp.w    numtracks-DB(a6),d7
  1058.         blt.s    plr_loop1_1
  1059.         addq.w    #1,d5
  1060.         cmp.w    numpages-DB(a6),d5
  1061.         bls.s    plr_loop1
  1062.         rts
  1063.  
  1064. ; *******************************************************************
  1065. ; DoPreFX: Perform effects that must be handled before note playing
  1066. ; *******************************************************************
  1067. ; args:        a6 = DB            d0 = command number (w)
  1068. ;        a5 = track data        d5 = note number
  1069. ;        a4 = song        d4 = data
  1070. ;                    d7 = track #
  1071. ; returns:    d0 = 0: play - d0 = 1: don't play
  1072.  
  1073. rtplay        MACRO
  1074.         moveq    #0,d0
  1075.         rts
  1076.         ENDM
  1077. rtnoplay    MACRO
  1078.         moveq    #1,d0
  1079.         rts
  1080.         ENDM
  1081.  
  1082. DoPreFX:    add.b    d0,d0    ;* 2
  1083.         move.w    f_table(pc,d0.w),d0
  1084.         jmp    fst(pc,d0.w)
  1085. f_table        dc.w    fx-fst,fx-fst,fx-fst,f_03-fst,fx-fst,fx-fst,fx-fst,fx-fst
  1086.         dc.w    f_08-fst,f_09-fst,fx-fst,f_0b-fst,f_0c-fst,fx-fst,fx-fst,f_0f-fst
  1087.         dc.w    fx-fst,fx-fst,fx-fst,fx-fst,fx-fst,f_15-fst,f_16-fst,fx-fst
  1088.         dc.w    fx-fst,f_19-fst,fx-fst,fx-fst,fx-fst,f_1d-fst,f_1e-fst,f_1f-fst
  1089. fst
  1090. ; ---------------- tempo (F)
  1091. f_0f        tst.b    d4        ;test effect qual..
  1092.         beq    fx0fchgblck    ;if effect qualifier (last 2 #'s)..
  1093.         cmp.b    #$f0,d4        ;..is zero, go to next block
  1094.         bhi.s    fx0fspecial    ;if it's F1-FF something special
  1095. ; ---------------- just an ordinary "change tempo"-request
  1096.         moveq    #0,d0        ;will happen!!!
  1097.         move.b    d4,d0
  1098.         bsr    _SetTempo    ;change The Tempo
  1099. fx        rtplay
  1100. ; ---------------- no, it was FFx, something special will happen!!
  1101. fx0fspecial:    cmp.b    #$f2,d4
  1102.         beq.s    f_1f
  1103.         cmp.b    #$f4,d4
  1104.         beq.s    f_1f
  1105.         cmp.b    #$f5,d4
  1106.         bne.s    isfxfe
  1107. ; ---------------- FF2 (or 1Fxx)
  1108. f_1f
  1109.     IFNE    HOLD
  1110.         move.b    trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  1111.         bne.s    f_1frts            ;not 0 -> OK
  1112.         st    trk_noteoffcnt(a5)    ;0 -> hold = 0xff (-1)
  1113.     ENDC
  1114. f_1frts        rtnoplay
  1115. isfxfe:        cmp.b    #$fe,d4
  1116.         bne.s    notcmdfe
  1117. ; ---------------- it was FFE, stop playing
  1118.         clr.w    mmd_pstate(a2)
  1119.         bsr.w    _End8Play
  1120.         addq.l    #8,sp    ;2 subroutine levels
  1121.         bra.w    plr_exit
  1122. f_ffe_no8    rtplay
  1123. notcmdfe:    cmp.b    #$fd,d4 ;change period
  1124.         bne.s    isfxff
  1125. ; ---------------- FFD, change the period, don't replay the note
  1126.         move.l    trk_periodtbl(a5),d1    ;period table
  1127.         beq.s    f_1frts
  1128.         movea.l    d1,a0
  1129.         move.b    trk_currnote(a5),d0
  1130.         subq.b    #1,d0    ;sub 1 to make "real" note number
  1131.     IFNE    CHECK
  1132.         bmi.s    f_1frts
  1133.     ENDC
  1134.         add.b    msng_playtransp(a4),d0
  1135.         add.b    trk_stransp(a5),d0
  1136.         add.w    d0,d0
  1137.         bmi.s    f_1frts
  1138.         move.w    0(a0,d0.w),trk_prevper(a5) ;get & push the period
  1139.         rtnoplay
  1140. isfxff:        cmp.b    #$ff,d4        ;note off??
  1141.         bne.s    f_ff_rts
  1142.         bsr.w    _ChannelO8
  1143. f_ff_rts    rtplay
  1144. ; ---------------- F00, called Pattern Break in ST
  1145. fx0fchgblck:    move.b    #1,nextblock-DB(a6)
  1146.         bra.s    f_ff_rts
  1147. ; ---------------- change volume
  1148. f_0c        btst    #4,msng_flags(a4)    ;look at flags
  1149.         bne.s    volhex8
  1150.         move.b    d4,d1        ;get again
  1151.         lsr.b    #4,d4        ;get number from left
  1152.         mulu    #10,d4        ;number of tens
  1153.         and.b    #$0f,d1        ;this time don't get tens
  1154.         add.b    d1,d4        ;add them
  1155. volhex8
  1156.     IFNE    CHECK
  1157.         cmp.b    #64,d4
  1158.         bhi.s    go_nocmd8
  1159.     ENDC
  1160.         movea.l    trk_audioaddr(a5),a0
  1161.         movea.l    ac_vol(a0),a0
  1162.         move.b    d4,(a0)
  1163. go_nocmd8    rtplay
  1164. ; ---------------- tempo2 change??
  1165. f_09
  1166.     IFNE    CHECK
  1167.         and.b    #$1F,d4
  1168.         bne.s    fx9chk
  1169.         moveq    #$20,d4
  1170.     ENDC
  1171. fx9chk:        move.b    d4,msng_tempo2(a4)
  1172. f_09_rts    rtplay
  1173. ; ---------------- block delay
  1174. f_1e        tst.w    blkdelay-DB(a6)
  1175.         bne.s    f_1e_rts
  1176.         addq.w    #1,d4
  1177.         move.w    d4,blkdelay-DB(a6)
  1178. f_1e_rts    rtplay
  1179. ; ---------------- finetune
  1180. f_15
  1181.     IFNE    CHECK
  1182.         cmp.b    #7,d4
  1183.         bgt.s    f_15_rts
  1184.         cmp.b    #-8,d4
  1185.         blt.s    f_15_rts
  1186.     ENDC
  1187.         move.b    d4,trk_finetune(a5)
  1188. f_15_rts    rtplay
  1189. ; ---------------- repeat loop
  1190. f_16        tst.b    d4
  1191.         bne.s    plr_dorpt
  1192.         move.w    mmd_pline(a2),rptline-DB(a6)
  1193.         bra.s    f_16_rts
  1194. plr_dorpt    tst.w    rptcounter-DB(a6)
  1195.         beq.s    plr_newrpt
  1196.         subq.w    #1,rptcounter-DB(a6)
  1197.         beq.s    f_16_rts
  1198.         bra.s    plr_setrptline
  1199. plr_newrpt    move.b    d4,rptcounter+1-DB(a6)
  1200. plr_setrptline    move.w    rptline-DB(a6),d0
  1201.         addq.w    #1,d0
  1202.         move.w    d0,nextblockline-DB(a6)
  1203. f_16_rts    rtplay
  1204. ; ---------------- note off time set??
  1205. f_08
  1206.     IFNE    HOLD
  1207.         and.b    #$0f,d4
  1208.         move.b    d4,trk_inithold(a5)    ;right = hold
  1209.     ENDC
  1210.         rtplay
  1211. ; ---------------- sample begin offset
  1212. f_19        lsl.w    #8,d4
  1213.         move.w    d4,trk_soffset(a5)
  1214. f_19_rts    rtplay
  1215. ; ---------------- cmd Bxx, "position jump"
  1216. f_0b
  1217.     IFNE    CHECK
  1218.         cmp.b    #'2',3(a2)
  1219.         bcc.s    chk0b_mmd2
  1220.         cmp.w    msng_songlen(a4),d4
  1221.         bhi.s    f_0b_rts
  1222.         bra.s    chk0b_end
  1223. chk0b_mmd2    move.w    mmd_pseq(a2),d0        ;get seq number
  1224.         movea.l    msng_pseqs(a4),a0    ;ptr to playseqs
  1225.         movea.l    0(a0,d0.w),a0        ;a0 = ptr to curr PlaySeq
  1226.         cmp.w    40(a0),d4        ;test song length
  1227.         bhi.s    f_0b_rts
  1228. chk0b_end
  1229.     ENDC
  1230.         move.w    d4,mmd_pseqnum(a2)
  1231.         st    nextblock-DB(a6)    ; = 1
  1232. f_0b_rts    rtplay
  1233. ; ---------------- cmd 1Dxx, jump to next seq, line # specified
  1234. f_1d        move.w    #$1ff,nextblock-DB(a6)
  1235.         addq.w    #1,d4
  1236.         move.w    d4,nextblockline-DB(a6)
  1237.         rtplay
  1238. ; ---------------- try portamento (3)
  1239. f_03        moveq    #0,d0
  1240.         move.b    trk_currnote(a5),d0
  1241.         subq.b    #1,d0        ;subtract note number
  1242.         bmi.s    plr_setfx3spd    ;0 -> set new speed
  1243.         move.l    trk_periodtbl(a5),d1
  1244.         beq.s    f_03_rts
  1245.         movea.l    d1,a0
  1246.         add.b    msng_playtransp(a4),d0    ;play transpose
  1247.         add.b    trk_stransp(a5),d0 ;and instrument transpose
  1248.         bmi.s    f_03_rts    ;again.. too low
  1249.         add.w    d0,d0
  1250.         move.w    0(a0,d0.w),trk_porttrgper(a5) ;period of this note is the target
  1251. plr_setfx3spd:    tst.b    d4        ;qual??
  1252.         beq.s    f_03_rts    ;0 -> do nothing
  1253.         move.b    d4,trk_prevportspd(a5)    ;store speed
  1254. f_03_rts    rtnoplay
  1255.  
  1256. ; *******************************************************************
  1257. ; DoFX: Handle effects, hold/fade etc.
  1258. ; *******************************************************************
  1259. DoFX        moveq    #0,d3
  1260.         move.b    mmd_counter(a2),d3
  1261.     IFNE    HOLD
  1262.         lea    trackdata8-DB(a6),a1
  1263. ; Loop 1: Hold/Fade handling
  1264.         moveq    #0,d7    ;clear track count
  1265. dofx_loop1    movea.l    (a1)+,a5
  1266. ; *******************************************************************
  1267. ; HoldAndFade: Handle hold/fade
  1268. ; *******************************************************************
  1269. ; args:        a5 = track data
  1270. ;        a6 = DB
  1271. ;        d7 = track #
  1272. ; scratches:    d0, d1, a0, a1
  1273.  
  1274. HoldAndFade    tst.b    trk_noteoffcnt(a5)
  1275.         bmi.s    plr_haf_dofx
  1276.         subq.b    #1,trk_noteoffcnt(a5)
  1277.         bpl.s    plr_haf_dofx
  1278.         bsr.w    _ChannelO8    ;hold time expired
  1279. plr_haf_dofx    addq.w    #1,d7
  1280.         cmp.w    numtracks-DB(a6),d7
  1281.         blt.s    dofx_loop1
  1282.     ENDC
  1283. ; Loop 2: Track command handling
  1284.         moveq    #0,d5    ;command page count
  1285. dofx_loop2    move.w    fxplineblk-DB(a6),d0
  1286.         bsr.w    GetBlockAddr
  1287.         movea.l    a0,a3
  1288.     IFNE    PLAYMMD0
  1289.         cmp.b    #'1',3(a2)
  1290.         bge.s    dofx_sbd_nommd0
  1291.         bsr.w    StoreBlkDimsMMD0
  1292.         bra.s    dofx_sbd_mmd0
  1293. dofx_sbd_nommd0
  1294.     ENDC
  1295.         bsr.w    StoreBlockDims
  1296. dofx_sbd_mmd0    move.w    d5,d1
  1297.         move.w    fxplineblk+2-DB(a6),d2
  1298.         movea.l    a3,a0
  1299.         bsr.s    GetCmdPointer
  1300.         movea.l    a0,a3
  1301.         moveq    #0,d7    ;clear track count
  1302.         lea    trackdata8-DB(a6),a1
  1303. dofx_loop2_1    movea.l    (a1)+,a5
  1304.         moveq    #0,d4
  1305.         move.b    (a3),d0            ;command #
  1306.         move.b    1(a3),d4        ;data byte
  1307.     IFNE    PLAYMMD0
  1308.         cmp.b    #3,d6            ;if adv == 3 -> MMD0
  1309.         bne.s    dofx_mmd12mask
  1310.         and.w    #$0F,d0
  1311.         bra.s    dofx_mmd0maskd
  1312. dofx_mmd12mask
  1313.     ENDC
  1314.         and.w    #$1F,d0
  1315. dofx_mmd0maskd    bsr.w    ChannelFX
  1316. dofx_lend2_1    adda.w    d6,a3            ;next track...
  1317.         addq.w    #1,d7
  1318.         cmp.w    numtracks-DB(a6),d7
  1319.         blt.s    dofx_loop2_1
  1320.         addq.w    #1,d5
  1321.         cmp.w    numpages-DB(a6),d5
  1322.         bls.s    dofx_loop2
  1323. ; Loop 3: Updating audio hardware
  1324.         moveq    #0,d7    ;clear track count
  1325.         lea    trackdata8-DB(a6),a1
  1326. dofx_loop3    movea.l    (a1)+,a5
  1327. ; *******************************************************************
  1328. ; UpdatePerVol:    Update audio registers (period & volume) after FX
  1329. ; *******************************************************************
  1330. UpdatePerVol    move.w    trk_prevper(a5),d1
  1331.         add.w    trk_vibradjust(a5),d1
  1332.         movea.l    trk_audioaddr(a5),a0
  1333.         sub.w    trk_arpadjust(a5),d1
  1334.         clr.l    trk_vibradjust(a5)    ;clr both adjusts
  1335.         move.w    d1,ac_per(a0)
  1336. dofx_lend3    addq.w    #1,d7
  1337.         cmp.w    numtracks-DB(a6),d7
  1338.         blt.s    dofx_loop3
  1339.         rts
  1340.  
  1341. ; *******************************************************************
  1342. ; GetCmdPointer: Return command pointer for track 0
  1343. ; *******************************************************************
  1344. ; args:        a0 = block pointer
  1345. ;        d1 = page number
  1346. ;        d2 = line number
  1347. ;        a2 = module
  1348. ; result:    a0 = command pointer (i.e. trk 0 note + 2)
  1349. ;        d6 = track advance (bytes)
  1350. ; scratches:    d0, d1, d2, a0
  1351. ; Note: no num_pages check! If numpages > 0 it can be assumed that
  1352. ; extra pages exist.
  1353.  
  1354. GetCmdPointer
  1355.     IFNE    PLAYMMD0
  1356.         cmp.b    #'1',3(a2)
  1357.         blt.s    GetCmdPtrMMD0
  1358.     ENDC
  1359.         mulu    (a0),d2        ;d2 = line # * numtracks
  1360.         add.l    d2,d2        ;d2 *= 2...
  1361.         subq.w    #1,d1
  1362.         bmi.s    gcp_page0
  1363.         movea.l    4(a0),a0
  1364.         movea.l    12(a0),a0
  1365.         add.w    d1,d1
  1366.         add.w    d1,d1
  1367.         movea.l    4(a0,d1.w),a0    ;command data
  1368.         adda.l    d2,a0
  1369.         moveq    #2,d6
  1370.         rts
  1371. gcp_page0    add.l    d2,d2        ;d2 *= 4
  1372.         lea    10(a0,d2.l),a0    ;offs: 4 = header, 2 = note
  1373.         moveq    #4,d6        ;track advance (bytes)
  1374.         rts
  1375.     IFNE    PLAYMMD0
  1376. GetCmdPtrMMD0    moveq    #0,d0
  1377.         move.b    (a0),d0        ;get numtracks
  1378.         mulu    d0,d2        ;line # * numtracks
  1379.         move.w    d2,d0
  1380.         add.w    d2,d2
  1381.         add.w    d0,d2        ; *= 3...
  1382.         lea    3(a0,d2.l),a0    ;offs: 2 = header, 1 = note
  1383.         moveq    #3,d6
  1384.         rts
  1385.     ENDC
  1386.  
  1387. ; *******************************************************************
  1388. ; GetBlockAddr: Return pointer to block
  1389. ; *******************************************************************
  1390. ; args:        d0 = block number
  1391. ; result:    a0 = block pointer
  1392. ; scratches: d0, a0
  1393.  
  1394. GetBlockAddr    movea.l    mmd_blockarr(a2),a0
  1395.         add.w    d0,d0
  1396.         add.w    d0,d0
  1397.         movea.l    0(a0,d0.w),a0
  1398.         rts
  1399.  
  1400. ; *******************************************************************
  1401. ; GetNoteDataAddr: Check & return addr. of current note
  1402. ; *******************************************************************
  1403. ;args:        d0 = pblock        a6 = DB
  1404. ;returns:    a3 = address
  1405. ;scratches:    d0, a0, d1
  1406.  
  1407. GetNoteDataAddr    bsr.w    GetBlockAddr
  1408.         movea.l    a0,a3
  1409.     IFNE    PLAYMMD0
  1410.         cmp.b    #'1',3(a2)
  1411.         blt.s    GetNDAddrMMD0
  1412.     ENDC
  1413.         bsr.w    StoreBlockDims
  1414.         move.w    numlines-DB(a6),d1
  1415.         move.w    mmd_pline(a2),d0
  1416.         cmp.w    d1,d0        ;check if block end exceeded...
  1417.         bls.s    plr_nolinex
  1418.         move.w    d1,d0
  1419. plr_nolinex    add.w    d0,d0
  1420.         add.w    d0,d0    ;d0 = d0 * 4
  1421.         mulu    (a3),d0
  1422.         lea    8(a3,d0.l),a3    ;address of current note
  1423.         rts
  1424.  
  1425.     IFNE    PLAYMMD0
  1426. GetNDAddrMMD0    bsr.w    StoreBlkDimsMMD0
  1427.         move.w    numlines-DB(a6),d1
  1428.         move.w    mmd_pline(a2),d0
  1429.         cmp.w    d1,d0        ;check if block end exceeded...
  1430.         bls.s    plr_nolinex2
  1431.         move.w    d1,d0
  1432. plr_nolinex2    move.w    d0,d1
  1433.         add.w    d0,d0
  1434.         add.w    d1,d0    ;d0 = d0 * 3
  1435.         moveq    #0,d1
  1436.         move.b    (a3),d1    ;numtracks
  1437.         mulu    d1,d0
  1438.         lea    2(a3,d0.l),a3    ;address of current note
  1439.         rts
  1440.     ENDC
  1441.  
  1442. ; *******************************************************************
  1443. ; StoreBlockDims: Store block dimensions
  1444. ; *******************************************************************
  1445. ; args:        a0 = block ptr, a6 = DB
  1446.  
  1447. StoreBlockDims    move.w    (a0)+,d0
  1448.         cmp.w    #8,d0
  1449.         ble.s    sbd_lt8
  1450.         moveq    #8,d0
  1451. sbd_lt8        move.w    d0,numtracks-DB(a6)    ;numtracks & lines
  1452.         move.w    (a0)+,numlines-DB(a6)
  1453.         tst.l    (a0)            :BlockInfo
  1454.         beq.s    sbd_1page
  1455.         movea.l    (a0),a0
  1456.         move.l    12(a0),d0        ;BlockInfo.pagetable
  1457.         beq.s    sbd_1page
  1458.         movea.l    d0,a0
  1459.         move.w    (a0),numpages-DB(a6)    ;num_pages
  1460.         rts
  1461. sbd_1page    clr.w    numpages-DB(a6)
  1462.         rts
  1463.  
  1464.     IFNE    PLAYMMD0
  1465. StoreBlkDimsMMD0
  1466.         clr.w    numpages-DB(a6)
  1467.         moveq    #0,d0
  1468.         move.b    (a0)+,d0        ;numtracks
  1469.         cmp.w    #8,d0
  1470.         ble.s    sbd_lt8_2
  1471.         moveq    #8,d0
  1472. sbd_lt8_2    move.w    d0,numtracks-DB(a6)
  1473.         move.b    (a0),d0            ;numlines
  1474.         move.w    d0,numlines-DB(a6)
  1475.         rts
  1476.     ENDC
  1477.  
  1478. ; *******************************************************************
  1479. ; ChannelFX:    Do an effect on a channel
  1480. ; *******************************************************************
  1481. ;args:                    d3 = counter
  1482. ;        a4 = song struct    d4 = command qual (long, byte used)
  1483. ;        a5 = track data ptr    
  1484. ;        a6 = DB            d0 = command (long, byte used)
  1485. ;                    d7 = track (channel) number
  1486. ;scratches: d0, d1, d4, a0
  1487.  
  1488. ChannelFX    add.b    d0,d0    ;* 2
  1489.         move.w    fx_table(pc,d0.w),d0
  1490.         jmp    fxs(pc,d0.w)
  1491. fx_table    dc.w    fx_00-fxs,fx_01-fxs,fx_02-fxs,fx_03-fxs,fx_04-fxs
  1492.         dc.w    fx_05-fxs,fx_06-fxs,fx_07-fxs,fx_xx-fxs,fx_xx-fxs
  1493.         dc.w    fx_0a-fxs,fx_xx-fxs,fx_xx-fxs,fx_0d-fxs,fx_xx-fxs
  1494.         dc.w    fx_0f-fxs
  1495.         dc.w    fx_xx-fxs,fx_11-fxs,fx_12-fxs,fx_13-fxs,fx_14-fxs
  1496.         dc.w    fx_xx-fxs,fx_xx-fxs,fx_xx-fxs,fx_18-fxs,fx_xx-fxs
  1497.         dc.w    fx_1a-fxs,fx_1b-fxs,fx_xx-fxs,fx_xx-fxs,fx_xx-fxs
  1498.         dc.w    fx_1f-fxs
  1499. fxs:
  1500. ;    **************************************** Effect 01 ******
  1501. fx_01        tst.b    d3
  1502.         bne.s    fx_01nocnt0
  1503.         btst    #5,msng_flags(a4)    ;FLAG_STSLIDE??
  1504.         bne.s    fx_01rts
  1505. fx_01nocnt0    move.w    trk_prevper(a5),d0
  1506.         sub.w    d4,d0
  1507.         cmp.w    #113,d0
  1508.         bge.s    fx_01noovf
  1509.         move.w    #113,d0
  1510. fx_01noovf    move.w    d0,trk_prevper(a5)
  1511. fx_xx        ;fx_xx is just a RTS
  1512. fx_01rts    rts
  1513. ;    **************************************** Effect 11 ******
  1514. fx_11        tst.b    d3
  1515.         bne.s    fx_11rts
  1516.         sub.w    d4,trk_prevper(a5)
  1517. fx_11rts    rts
  1518. ;    **************************************** Effect 02 ******
  1519. fx_02        tst.b    d3
  1520.         bne.s    fx_02nocnt0
  1521.         btst    #5,msng_flags(a4)
  1522.         bne.s    fx_02rts
  1523. fx_02nocnt0    add.w    d4,trk_prevper(a5)
  1524. fx_02rts    rts
  1525. ;    **************************************** Effect 12 ******
  1526. fx_12        tst.b    d3
  1527.         bne.s    fx_12rts
  1528.         add.w    d4,trk_prevper(a5)
  1529. fx_12rts    rts
  1530. ;    **************************************** Effect 00 ******
  1531. fx_00        tst.b    d4    ;both fxqualifiers are 0s: no arpeggio
  1532.         beq.s    fx_00rts
  1533.         move.l    d3,d0
  1534.         divu    #3,d0
  1535.         swap    d0
  1536.         subq.b    #1,d0
  1537.         bgt.s    fx_arp2
  1538.         blt.s    fx_arp0
  1539.         and.b    #$0f,d4
  1540.         bra.s    fx_doarp
  1541. fx_arp0        lsr.b    #4,d4
  1542.         bra.s    fx_doarp
  1543. fx_arp2        moveq    #0,d4
  1544. fx_doarp:    move.b    (a5),d0
  1545.         subq.b    #1,d0        ;-1 to make it 0 - 127
  1546.         add.b    msng_playtransp(a4),d0    ;add play transpose
  1547.         add.b    trk_stransp(a5),d0    ;add instrument transpose
  1548.         add.b    d0,d4
  1549.         move.l    trk_periodtbl(a5),d1
  1550.         beq.s    fx_00rts
  1551.         movea.l    d1,a0
  1552.         add.b    d0,d0
  1553.         move.w    0(a0,d0.w),d0    ;base note period
  1554.         add.b    d4,d4
  1555.         sub.w    0(a0,d4.w),d0    ;calc difference from base note
  1556.         move.w    d0,trk_arpadjust(a5)
  1557. fx_00rts    rts
  1558. ;    **************************************** Effect 04 ******
  1559. fx_14        move.b    #6,trk_vibshift(a5)
  1560.         bra.s    vib_cont
  1561. fx_04        move.b    #5,trk_vibshift(a5)
  1562. vib_cont    tst.b    d3
  1563.         bne.s    nonvib
  1564.         move.b    d4,d1
  1565.         beq.s    nonvib
  1566.         and.w    #$0f,d1
  1567.         beq.s    plr_chgvibspd
  1568.         move.w    d1,trk_vibrsz(a5)
  1569. plr_chgvibspd    and.b    #$f0,d4
  1570.         beq.s    nonvib
  1571.         lsr.b    #3,d4
  1572.         and.b    #$3e,d4
  1573.         move.b    d4,trk_vibrspd(a5)
  1574. nonvib        move.b    trk_vibroffs(a5),d0
  1575.         lsr.b    #2,d0
  1576.         and.w    #$1f,d0
  1577.         moveq    #0,d1
  1578.         move.b    sinetable(pc,d0.w),d0
  1579.         ext.w    d0
  1580.         muls    trk_vibrsz(a5),d0
  1581.         move.b    trk_vibshift(a5),d1
  1582.         asr.w    d1,d0
  1583.         move.w    d0,trk_vibradjust(a5)
  1584.         move.b    trk_vibrspd(a5),d0
  1585.         add.b    d0,trk_vibroffs(a5)
  1586. fx_04rts    rts
  1587. sinetable:    dc.b    0,25,49,71,90,106,117,125,127,125,117,106,90,71,49
  1588.         dc.b    25,0,-25,-49,-71,-90,-106,-117,-125,-127,-125,-117
  1589.         dc.b    -106,-90,-71,-49,-25,0
  1590. ;    **************************************** Effect 06 ******
  1591.         EVEN
  1592. fx_06:        tst.b    d3
  1593.         bne.s    fx_06nocnt0
  1594.         btst    #5,msng_flags(a4)
  1595.         bne.s    fx_04rts
  1596. fx_06nocnt0    bsr.s    plr_volslide        ;Volume slide
  1597.         bra.s    nonvib            ;+ Vibrato
  1598. ;    **************************************** Effect 07 ******
  1599. fx_07        tst.b    d3
  1600.         bne.s    nontre
  1601.         move.b    d4,d1
  1602.         beq.s    nontre
  1603.         and.w    #$0f,d1
  1604.         beq.s    plr_chgtrespd
  1605.         move.w    d1,trk_tremsz(a5)
  1606. plr_chgtrespd    and.b    #$f0,d4
  1607.         beq.s    nontre
  1608.         lsr.b    #2,d4
  1609.         and.b    #$3e,d4
  1610.         move.b    d4,trk_tremspd(a5)
  1611. nontre        move.b    trk_tremoffs(a5),d0
  1612.         lsr.b    #3,d0
  1613.         and.w    #$1f,d0
  1614.         lea    sinetable(pc),a0
  1615.         move.b    0(a0,d0.w),d1
  1616.         ext.w    d1
  1617.         muls    trk_tremsz(a5),d1
  1618.         asr.w    #7,d1
  1619.         move.b    trk_tremspd(a5),d0
  1620.         add.b    d0,trk_tremoffs(a5)
  1621.         add.b    trk_prevvol(a5),d1
  1622.         bpl.s    tre_pos
  1623.         moveq    #0,d1
  1624. tre_pos        cmp.b    #64,d1
  1625.         ble.s    tre_no2hi
  1626.         moveq    #64,d1
  1627. tre_no2hi    move.b    d1,trk_tempvol(a5)
  1628.         rts
  1629. ;    ********* VOLUME SLIDE FUNCTION *************************
  1630. plr_volslide    move.b    d4,d0
  1631.         moveq    #0,d1
  1632.         move.b    trk_prevvol(a5),d1 ;move previous vol to d1
  1633.         and.b    #$f0,d0
  1634.         bne.s    crescendo
  1635.         sub.b    d4,d1    ;sub from prev. vol
  1636. voltest0    bpl.s    novolover64
  1637.         moveq    #0,d1    ;volumes under zero not accepted
  1638.         bra.s    novolover64
  1639. crescendo:    lsr.b    #4,d0
  1640.         add.b    d0,d1
  1641. voltest        cmp.b    #64,d1
  1642.         ble.s    novolover64
  1643.         moveq    #64,d1
  1644. novolover64    movea.l    trk_audioaddr(a5),a0
  1645.         movea.l    ac_vol(a0),a0
  1646.         move.b    d1,(a0)
  1647. volsl_rts    rts
  1648. ;    **************************************** Effect 0D/0A ***
  1649. fx_0a:
  1650. fx_0d:        tst.b    d3
  1651.         bne.s    plr_volslide
  1652.         btst    #5,msng_flags(a4)
  1653.         beq.s    plr_volslide
  1654.         rts
  1655. ;    **************************************** Effect 05 ******
  1656. fx_05:        tst.b    d3
  1657.         bne.s    fx_05nocnt0
  1658.         btst    #5,msng_flags(a4)
  1659.         bne.s    fx_05rts
  1660. fx_05nocnt0    bsr.s    plr_volslide
  1661.         bra.s    fx_03nocnt0
  1662. fx_05rts    rts
  1663. ;    **************************************** Effect 1A ******
  1664. fx_1a        tst.b    d3
  1665.         bne.s    volsl_rts
  1666.         move.b    trk_prevvol(a5),d1
  1667.         add.b    d4,d1
  1668.         bra.s    voltest
  1669. ;    **************************************** Effect 1B ******
  1670. fx_1b        tst.b    d3
  1671.         bne.s    volsl_rts
  1672.         move.b    trk_prevvol(a5),d1
  1673.         sub.b    d4,d1
  1674.         bra.s    voltest0
  1675. ;    **************************************** Effect 03 ******
  1676. fx_03        tst.b    d3
  1677.         bne.s    fx_03nocnt0
  1678.         btst    #5,msng_flags(a4)
  1679.         bne.s    fx_03rts
  1680. fx_03nocnt0    move.w    trk_porttrgper(a5),d0    ;d0 = target period
  1681.         beq.s    fx_03rts
  1682.         move.w    trk_prevper(a5),d1    ;d1 = curr. period
  1683.         move.b    trk_prevportspd(a5),d4    ;get prev. speed
  1684.         cmp.w    d0,d1
  1685.         bhi.s    subper    ;curr. period > target period
  1686.         add.w    d4,d1    ;add the period
  1687.         cmp.w    d0,d1
  1688.         bge.s    targreached
  1689.         bra.s    targnreach
  1690. subper:        sub.w    d4,d1    ;subtract
  1691.         cmp.w    d0,d1    ;compare current period to target period
  1692.         bgt.s    targnreach
  1693. targreached:    move.w    trk_porttrgper(a5),d1 ;eventually push target period
  1694.         clr.w    trk_porttrgper(a5) ;now we can forget everything
  1695. targnreach:    move.w    d1,trk_prevper(a5)
  1696. fx_03rts    rts
  1697. ;    **************************************** Effect 13 ******
  1698. fx_13:        cmp.b    #3,d3
  1699.         bge.s    fx_13rts    ;if counter < 3
  1700.         neg.w    d4
  1701.         move.w    d4,trk_vibradjust(a5)    ;subtract effect qual...
  1702. fx_13rts    rts
  1703. ;    **************************************** Effect 18 ******
  1704. fx_18        cmp.b    d4,d3
  1705.         bne.s    fx_18rts
  1706.         clr.b    trk_prevvol(a5)
  1707. fx_18rts    rts
  1708. ;    **************************************** Effect 1F ******
  1709. fx_1f        move.b    d4,d1
  1710.         lsr.b    #4,d4        ;note delay
  1711.         beq.s    nonotedelay
  1712.         cmp.b    d4,d3        ;compare to counter
  1713.         blt.s    fx_18rts    ;tick not reached
  1714.         bne.s    nonotedelay
  1715.         bra    playfxnote    ;trigger note
  1716. nonotedelay    and.w    #$0f,d1        ;retrig?
  1717.         beq.s    fx_18rts
  1718.         moveq    #0,d0
  1719.         move.b    d3,d0
  1720.         divu    d1,d0
  1721.         swap    d0        ;get modulo of counter/tick
  1722.         tst.w    d0
  1723.         bne.s    fx_18rts
  1724.         bra    playfxnote    ;retrigger
  1725. ;    **************************************** Effect 0F ******
  1726. ;    see below...
  1727. ;    *********************************************************
  1728.  
  1729. ; **** a separate routine for handling command 0F
  1730. fx_0f        cmp.b    #$f1,d4
  1731.         bne.s    no0ff1
  1732.         cmp.b    #3,d3
  1733.         beq.s    playfxnote
  1734.         rts
  1735. no0ff1:        cmp.b    #$f2,d4
  1736.         bne.s    no0ff2
  1737.         cmp.b    #3,d3
  1738.         beq.s    playfxnote
  1739.         rts
  1740. no0ff2:        cmp.b    #$f3,d4
  1741.         bne.s    no0ff3
  1742.         move.b    d3,d0
  1743.         beq.s    cF_rts
  1744.         and.b    #1,d0        ;is 2 or 4
  1745.         bne.s    cF_rts
  1746. playfxnote:    moveq    #0,d1
  1747.         move.b    trk_currnote(a5),d1    ;get note # of curr. note
  1748.         beq.s    cF_rts
  1749.         move.b    trk_noteoffcnt(a5),d0    ;get hold counter
  1750.         bmi.s    pfxn_nohold        ;no hold, or hold over
  1751.         add.b    d3,d0            ;increase by counter val
  1752.         bra.s    pfxn_hold
  1753. pfxn_nohold    move.b    trk_inithold(a5),d0    ;get initial hold
  1754.         bne.s    pfxn_hold
  1755.         st    d0
  1756. pfxn_hold    move.b    d0,trk_noteoffcnt(a5)
  1757.         movem.l    a1/a3/d3/d6,-(sp)
  1758.         moveq    #0,d3
  1759.         move.b    trk_previnstr(a5),d3    ;and prev. sample #
  1760.         movea.l    trk_previnstra(a5),a3
  1761.         bsr    _PlayNote8
  1762.         movem.l    (sp)+,a1/a3/d3/d6
  1763. cF_rts        rts
  1764. no0ff3:        cmp.b    #$f4,d4        ;triplet cmd 1
  1765.         bne.s    no0ff4
  1766.         moveq    #0,d0
  1767.         move.b    msng_tempo2(a4),d0
  1768.         divu    #3,d0
  1769.         cmp.b    d0,d3
  1770.         beq.s    playfxnote
  1771.         rts
  1772. no0ff4        cmp.b    #$f5,d4        ;triplet cmd 2
  1773.         bne.s    no0ff5
  1774.         moveq    #0,d0
  1775.         move.b    msng_tempo2(a4),d0
  1776.         divu    #3,d0
  1777.         add.w    d0,d0
  1778.         cmp.b    d0,d3
  1779.         beq.s    playfxnote
  1780.         rts
  1781. no0ff5        cmp.b    #$f8,d4        ;f8 = filter off
  1782.         beq.s    plr_filteroff
  1783.         cmp.b    #$f9,d4        ;f9 = filter on
  1784.         bne.s    cF_rts
  1785.         bclr    #1,$bfe001
  1786.         bset    #0,msng_flags(a4)
  1787.         rts
  1788. plr_filteroff:    bset    #1,$bfe001
  1789.         bclr    #0,msng_flags(a4)
  1790.         rts
  1791.  
  1792. _SetTempo:    move.l    _module8-DB(a6),d1
  1793.         beq.s    ST_x
  1794.         movea.l    d1,a0
  1795.         movea.l    mmd_songinfo(a0),a0
  1796.         move.w    d0,msng_deftempo(a0)
  1797.         tst.w    d0
  1798.         ble.s    ST_maxszcnt
  1799.         cmp.w    #9,d0
  1800.         bls.s    ST_nodef8tempo
  1801. ST_maxszcnt    moveq    #10,d0
  1802. ST_nodef8tempo    add.b    #9,d0
  1803.         move.b    d0,currchszcnt-DB+1(a6)
  1804.         tst.b    msng_flags(a0)    ;test SLOWHQ compatibility flag
  1805.         lea    eightchsizes-10-DB(a6),a0
  1806.         bmi.s    ST_slowhq    ;SLOWHQ set
  1807.         tst.b    _hq-DB(a6)
  1808.         beq.s    ST_nohq
  1809.         move.b    10(a0,d0.w),d0    ;get buffersize / 4
  1810.         add.w    d0,d0        ;->buffersize / 2
  1811.         bra.s    ST_hqcont
  1812. ST_slowhq    move.b    0(a0,d0.w),d0
  1813.         add.w    d0,d0
  1814.         bra.s    ST_hqcont
  1815. ST_nohq        move.b    0(a0,d0.w),d0    ;get buffersize / 2
  1816. ST_hqcont    move.w    d0,currchsize2-DB(a6)
  1817.         asl.w    #3,d0        ;get buffersize * 4
  1818.         move.w    d0,currchsize-DB(a6)
  1819. ST_x        rts
  1820.  
  1821. _Rem8chan:    move.l    a6,-(sp)
  1822.         lea    DB,a6
  1823.         move.b    eightrkon-DB(a6),d0
  1824.         beq.s    no8init
  1825.         clr.b    eightrkon-DB(a6)
  1826.         move.w    #1<<7,$dff09a
  1827.         move.l    prevaud-DB(a6),d0
  1828.         beq.s    no8init
  1829.         move.l    d0,a1
  1830.         move.l    4,a6
  1831.         moveq    #7,d0
  1832.         jsr    -$a2(a6)
  1833. no8init        move.l    (sp)+,a6
  1834.         rts
  1835.  
  1836. _End8Play:    tst.b    play8
  1837.         beq.s    noend8play
  1838.         move.w    #1<<7,$dff09a
  1839.         move.w    #$F,$dff096
  1840.         clr.b    play8
  1841. noend8play    rts
  1842.  
  1843. ; *************************************************************************
  1844. ; *************************************************************************
  1845. ; ***********          P U B L I C   F U N C T I O N S          ***********
  1846. ; *************************************************************************
  1847. ; *************************************************************************
  1848.  
  1849.         xdef    _PlayModule8
  1850.         xdef    _InitPlayer8,_RemPlayer8,_StopPlayer8
  1851.         xdef    _ContModule8
  1852.  
  1853. ; *************************************************************************
  1854. ; InitModule8(a0 = module) -- extract expansion data etc.. from the module
  1855. ; *************************************************************************
  1856.  
  1857. _InitModule8:    movem.l    a2-a3/a6/d2,-(sp)
  1858.         lea    DB,a6
  1859.         move.l    a0,d0
  1860.         beq.w    IM_exit            ;0 => xit
  1861.         lea    holdvals-DB(a6),a2
  1862.         movea.l    mmd_songinfo(a0),a3
  1863.         move.l    mmd_expdata(a0),d0    ;expdata...
  1864.         beq.s    IM_clrhlddec        ;none here
  1865.         move.l    d0,a1
  1866.         move.l    4(a1),d0        ;exp_smp
  1867.         beq.s    IM_clrhlddec    ;again.. nothing
  1868.         move.l    d0,a0        ;InstrExt...
  1869.         move.w    8(a1),d2    ;# of entries
  1870.         beq.s    IM_clrhlddec
  1871.         subq.w    #1,d2        ;- 1 (for dbf)
  1872.         move.w    10(a1),d0    ;entry size
  1873. IM_loop1    clr.b    63(a2)        ;clear finetune
  1874.         cmp.w    #3,d0
  1875.         ble.s    IM_noftune
  1876.         move.b    3(a0),63(a2)
  1877. IM_noftune    clr.b    126(a2)        ;clear flags
  1878.         cmp.w    #6,d0
  1879.         blt.s    IM_noflags
  1880.         move.b    5(a0),126(a2)    ;InstrExt.flags -> flags
  1881.         bra.s    IM_gotflags
  1882. IM_noflags    cmp.w    #1,inst_replen(a3)
  1883.         bls.s    IM_gotflags
  1884.         bset    #0,126(a2)
  1885. IM_gotflags    move.b    (a0),(a2)+    ;InstrExt.hold -> holdvals
  1886.         adda.w    d0,a0        ;ptr to next InstrExt
  1887.         addq.l    #8,a3        ;next instrument...
  1888.         dbf    d2,IM_loop1
  1889.         bra.s    IM_exit
  1890. IM_clrhlddec    moveq    #125,d0        ;no InstrExt => clear holdvals/decays
  1891. IM_loop2    clr.b    (a2)+
  1892.         dbf    d0,IM_loop2
  1893. ; -------- For (very old) MMDs, with no InstrExt, set flags/SSFLG_LOOP.
  1894.         lea    flags,a2
  1895.         moveq    #62,d0
  1896. IM_loop4    cmp.w    #1,inst_replen(a3)
  1897.         bls.s    IM_noreptflg
  1898.         bset    #0,(a2)
  1899. IM_noreptflg    addq.l    #1,a2
  1900.         addq.l    #8,a3        ;next inst
  1901.         dbf    d0,IM_loop4
  1902. IM_exit        movem.l    (sp)+,a2-a3/a6/d2
  1903.         rts
  1904.  
  1905.  
  1906. ; *************************************************************************
  1907. ; ContModule8(a0 = module) -- continue playing
  1908. ; *************************************************************************
  1909. _ContModule8    bsr.w    _End8Play
  1910.         moveq    #0,d0
  1911.         bra.s    contpoint8
  1912. ; *************************************************************************
  1913. ; PlayModule8(a0 = module)  -- init and play a module
  1914. ; *************************************************************************
  1915. _PlayModule8:    st    d0
  1916. contpoint8    move.l    a6,-(sp)
  1917.         lea    DB,a6
  1918.         movem.l    a0/d0,-(sp)
  1919.         bsr    _InitModule8
  1920.         movem.l    (sp)+,a0/d0
  1921.     IFNE    AUDDEV
  1922.         tst.b    audiodevopen-DB(a6)
  1923.         beq    PM_end        ;resource allocation failure
  1924.     ENDC
  1925.         move.l    a0,d1
  1926.         beq.w    PM_end        ;module failure
  1927.         bsr.w    _End8Play
  1928.         clr.l    _module8-DB(a6)
  1929.         clr.l    tmpvol-DB(a6)
  1930.         move.w    _modnum8,d1
  1931.         beq.s    PM_modfound
  1932. PM_nextmod    tst.l    mmd_expdata(a0)
  1933.         beq.s    PM_modfound
  1934.         move.l    mmd_expdata(a0),a1
  1935.         tst.l    (a1)
  1936.         beq.s    PM_modfound        ;no more modules here!
  1937.         move.l    (a1),a0
  1938.         subq.w    #1,d1
  1939.         bgt.s    PM_nextmod
  1940. PM_modfound    cmp.b    #'T',3(a0)
  1941.         bne.s    PM_nomodT
  1942.         move.b    #'0',3(a0)    ;change MCNT to MCN0
  1943. PM_nomodT    movea.l    mmd_songinfo(a0),a1        ;song
  1944.         move.b    msng_tempo2(a1),mmd_counter(a0)    ;init counter
  1945.         btst    #0,msng_flags(a1)
  1946.         bne.s    PM_filon
  1947.         bset    #1,$bfe001
  1948.         bra.s    PM_filset
  1949. PM_filon    bclr    #1,$bfe001
  1950. PM_filset    tst.b    d0
  1951.         beq.s    PM_noclr
  1952.         clr.l    mmd_pline(a0)
  1953.         clr.l    rptline-DB(a6)
  1954.         clr.w    blkdelay-DB(a6)
  1955. ; ---------- Set 'pblock' and 'pseq' to correct values...
  1956. PM_noclr    cmp.b    #'2',3(a0)
  1957.         bcs.s    PM_oldpbset
  1958.         move.w    mmd_psecnum(a0),d1
  1959.         move.l    a2,-(sp)        ;need extra register
  1960.         movea.l    msng_sections(a1),a2
  1961.         add.w    d1,d1
  1962.         move.w    0(a2,d1.w),d1        ;get sequence number
  1963.         add.w    d1,d1
  1964.         add.w    d1,d1
  1965.         move.w    d1,mmd_pseq(a0)
  1966.         movea.l    msng_pseqs(a1),a2
  1967.         movea.l    0(a2,d1.w),a2        ;PlaySeq...
  1968.         move.w    mmd_pseqnum(a0),d1
  1969.         add.w    d1,d1
  1970.         move.w    42(a2,d1.w),d1        ;and the correct block..
  1971.         move.l    (sp)+,a2
  1972.         bra.s    PM_setblk
  1973. PM_oldpbset    move.w    mmd_pseqnum(a0),d1
  1974.         add.w    #msng_playseq,d1
  1975.         move.b    0(a1,d1.w),d1        ;get first playseq entry
  1976.         ext.w    d1
  1977. PM_setblk    move.w    d1,mmd_pblock(a0)
  1978.         move.w    #-1,mmd_pstate(a0)
  1979.         move.l    a0,_module8-DB(a6)
  1980.         move.l    mmd_expdata(a0),d0
  1981.         beq.s    PM_start
  1982.         movea.l    d0,a0
  1983.         lea    36(a0),a0    ;track split mask
  1984.         bsr.s    _SetChMode
  1985. PM_start
  1986.     IFNE    FASTMEMPLAY
  1987.         tst.w    _fastmemplay8-DB(a6)
  1988.         beq.s    PM_nofmp
  1989.         move.l    a1,-(sp)
  1990.         bsr.w    _InitFastMemPlayer
  1991.         movea.l    (sp)+,a1
  1992. PM_nofmp
  1993.     ENDC
  1994.         bsr.s    _Start8Play
  1995. PM_end        move.l    (sp)+,a6
  1996.         rts
  1997.  
  1998. _SetChMode    ;a0 = address of 4 UBYTEs
  1999.         movem.l    a2/d2,-(sp)
  2000.         lea    trksplit-DB(a6),a2
  2001.         lea    t07d+trk_split-DB(a6),a1
  2002.         moveq    #3,d0
  2003.         moveq    #0,d1
  2004. scm_loop    lsr.b    #1,d1
  2005.         move.b    (a0)+,d2
  2006.         beq.s    scm_split
  2007.         moveq    #0,d2
  2008.         bra.s    scm_nosplit
  2009. scm_split    or.b    #8,d1
  2010.         st    d2
  2011. scm_nosplit    move.b    d2,(a1)
  2012.         move.b    d2,4*TRACKDATASZ(a1)
  2013.         lea    TRACKDATASZ(a1),a1
  2014.         move.b    d2,(a2)+
  2015.         dbf    d0,scm_loop
  2016.         move.w    d1,chdmamask-DB(a6)
  2017.         movem.l    (sp)+,a2/d2
  2018. rts:        rts
  2019.  
  2020. _Start8Play:    ;d0 = pstate
  2021.         move.l    a6,-(sp)
  2022.         lea    DB,a1
  2023.         lea    _audiobuff,a0
  2024.         move.w    #1600-1,d1
  2025. clrbuffloop:    clr.l    (a0)+        ;clear track buffers
  2026.         dbf    d1,clrbuffloop
  2027.         move.l    _module8-DB(a1),d0
  2028.         beq.s    rts
  2029.         move.l    d0,a0
  2030.         movea.l    mmd_songinfo(a0),a0
  2031.         move.w    msng_deftempo(a0),d0    ;get deftempo
  2032.         bsr.w    _SetTempo
  2033.         lea    $dff000,a0
  2034.         tst.b    _hq-DB(a1)
  2035.         bne.s    s8p_hq
  2036.         move.w    #227,d1
  2037.         bra.s    s8p_nohq
  2038. s8p_hq        move.w    #124,d1
  2039. s8p_nohq    move.w    currchsize2-DB(a1),d0
  2040.         move.l    #_audiobuff,$a0(a0)
  2041.         move.w    d0,$a4(a0)    ;set audio buffer sizes
  2042.         move.w    d1,$a6(a0)
  2043.         tst.b    trksplit+1-DB(a1)
  2044.         beq.s    1$
  2045.         move.l    #_audiobuff+800,$b0(a0)
  2046.         move.w    d0,$b4(a0)
  2047.         move.w    d1,$b6(a0)
  2048. 1$        tst.b    trksplit+2-DB(a1)
  2049.         beq.s    2$
  2050.         move.l    #_audiobuff+1600,$c0(a0)
  2051.         move.w    d0,$c4(a0)
  2052.         move.w    d1,$c6(a0)
  2053. 2$        tst.b    trksplit+3-DB(a1)
  2054.         beq.s    3$
  2055.         move.l    #_audiobuff+2400,$d0(a0)
  2056.         move.w    d0,$d4(a0)
  2057.         move.w    d1,$d6(a0)
  2058. 3$        moveq    #64,d1
  2059.         move.w    d1,$a8(a0)
  2060.         move.w    d1,$b8(a0)
  2061.         move.w    d1,$c8(a0)
  2062.         move.w    d1,$d8(a0)
  2063.         clr.b    whichbuff-DB(a1)
  2064.         movea.l    4.w,a6
  2065.         move.w    #$780,$9a(a0)    ;audio interrupts off
  2066.         tst.b    play8-DB(a1)
  2067.         bne.s    4$
  2068.         movem.l    a0/a1,-(sp)
  2069.         moveq    #7,d0        ;Audio channel 0 interrupt
  2070.         lea    audiointerrupt,a1
  2071.         jsr    -$a2(a6)    ;SetIntVector()
  2072.         movem.l    (sp)+,a0/a1
  2073. 4$        jsr    -$78(a6)    ;Disable()
  2074.         lea    track0hw-DB(a1),a1
  2075.         moveq    #7,d1
  2076. clrtrkloop    clr.l    (a1)
  2077.         clr.w    ac_per(a1)
  2078.         adda.w    #SIZE4TRKHW/4,a1
  2079.         dbf    d1,clrtrkloop
  2080.         move.w    #$F,$96(a0)    ;audio DMA off
  2081.         bsr.w    _Wait1line    ;wait until all stopped
  2082.         lea    DB,a1
  2083.         st    play8-DB(a1)
  2084.         move.w    #$8080,$9a(a0)
  2085.         move.w    chdmamask-DB(a1),d1
  2086.         bset    #15,d1
  2087.         move.w    d1,$96(a0)
  2088.         movea.l    4.w,a6
  2089.         jsr    -$7e(a6)    ;Enable()
  2090.         move.l    (sp)+,a6
  2091.         rts
  2092. ; *************************************************************************
  2093. ; InitPlayer8() -- allocate interrupt, audio, serial port etc...
  2094. ; *************************************************************************
  2095. _InitPlayer8:    bsr.s    _AudioInit
  2096.         tst.l    d0
  2097.         bne.s    IP_error
  2098.         rts
  2099. IP_error    bsr.s    _RemPlayer8
  2100.         moveq    #-1,d0
  2101.         rts
  2102. ; *************************************************************************
  2103. ; StopPlayer8() -- stop music
  2104. ; *************************************************************************
  2105. _StopPlayer8:    move.l    _module8,d0
  2106.         beq.s    SP_nomod
  2107.         movea.l    d0,a0
  2108.         clr.w    mmd_pstate(a0)
  2109.         clr.l    _module8
  2110. SP_nomod    bsr.w    _End8Play
  2111.     IFNE    FASTMEMPLAY
  2112.         bra.w    _RemAudioInts
  2113.     ELSEIF
  2114.         rts
  2115.     ENDC
  2116.  
  2117. ; *************************************************************************
  2118. ; RemPlayer8() -- free interrupt, audio, serial port etc..
  2119. ; *************************************************************************
  2120. _RemPlayer8:    bsr.s    _StopPlayer8
  2121. ;        vvvvvvvvvvvvvvvv  to _AudioRem
  2122. ; *************************************************************************
  2123. _AudioRem:    movem.l    a5-a6,-(sp)
  2124.         lea    DB,a5
  2125.         bsr.w    _Rem8chan
  2126.     IFNE    AUDDEV
  2127.         movea.l    4,a6
  2128.         tst.b    audiodevopen-DB(a5)
  2129.         beq.s    rem2
  2130.         clr.b    audiodevopen-DB(a5)
  2131.         move.w    #$000f,$dff096    ;stop audio DMA
  2132. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ close audio.device
  2133.         lea    allocreq-DB(a5),a1
  2134.         jsr    -$1c2(a6)    ;CloseDevice()
  2135. rem2:        moveq    #0,d0
  2136.         move.b    sigbitnum-DB(a5),d0
  2137.         bmi.s    rem3
  2138. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ free signal bit
  2139.         jsr    -$150(a6)    ;FreeSignal()
  2140.         st    sigbitnum-DB(a5)
  2141.     ENDC
  2142. rem3:        movem.l    (sp)+,a5-a6
  2143.         rts
  2144.  
  2145.  
  2146. _AudioInit:    movem.l    a4/a6/d2-d3,-(sp)
  2147.         lea    DB,a4
  2148.         movea.l    4.w,a6
  2149.     IFNE    AUDDEV
  2150.         moveq    #0,d2
  2151. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ alloc signal bit
  2152.         moveq    #1,d2
  2153.         moveq    #-1,d0
  2154.         jsr    -$14a(a6)    ;AllocSignal()
  2155.         tst.b    d0
  2156.         bmi.w    initerr
  2157.         move.b    d0,sigbitnum-DB(a4)
  2158. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ prepare IORequest
  2159.         lea    allocport-DB(a4),a1
  2160.         move.b    d0,15(a1)    ;set mp_SigBit
  2161.         move.l    a1,-(sp)
  2162.         suba.l    a1,a1
  2163.         jsr    -$126(a6)    ;FindTask(0)
  2164.         move.l    (sp)+,a1
  2165.         move.l    d0,16(a1)    ;set mp_SigTask
  2166.         lea    reqlist-DB(a4),a0
  2167.         move.l    a0,(a0)        ;NEWLIST begins...
  2168.         addq.l    #4,(a0)
  2169.         clr.l    4(a0)
  2170.         move.l    a0,8(a0)    ;NEWLIST ends...
  2171. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ open audio.device
  2172.         moveq    #2,d2
  2173.         lea    allocreq-DB(a4),a1
  2174.         lea    audiodevname-DB(a4),a0
  2175.         moveq    #0,d0
  2176.         moveq    #0,d1
  2177.         jsr    -$1bc(a6)    ;OpenDevice()
  2178.         tst.b    d0
  2179.         bne.w    initerr
  2180.         st.b    audiodevopen-DB(a4)
  2181.     ENDC
  2182.         move.w    #$0780,$dff09a
  2183.         bsr.s    _InitPlayRoutine
  2184.         st    eightrkon-DB(a4)
  2185.         moveq    #0,d0
  2186. initret:    movem.l    (sp)+,a4/a6/d2-d3
  2187.         rts
  2188. initerr:    move.l    d2,d0
  2189.         bra.s    initret
  2190.  
  2191. _InitPlayRoutine
  2192.         lea    trackdata8,a0
  2193.         movea.l    (a0)+,a1
  2194.         move.l    #track0hw,d0
  2195.         moveq    #SIZE4TRKHW/4,d1
  2196.         move.l    d0,trk_audioaddr(a1)
  2197.         add.l    d1,d0
  2198.         movea.l    (a0)+,a1
  2199.         move.l    d0,trk_audioaddr(a1)
  2200.         add.l    d1,d0
  2201.         move.l    #fmpstructs,trk_fmp(a1)
  2202.         movea.l    (a0)+,a1
  2203.         move.l    d0,trk_audioaddr(a1)
  2204.         add.l    d1,d0
  2205.         move.l    #fmpstructs+fmp_sizeof,trk_fmp(a1)
  2206.         movea.l    (a0)+,a1
  2207.         move.l    d0,trk_audioaddr(a1)
  2208.         add.l    d1,d0
  2209.         move.l    #fmpstructs+fmp_sizeof*2,trk_fmp(a1)
  2210.         movea.l    (a0)+,a1
  2211.         move.l    d0,trk_audioaddr(a1)
  2212.         add.l    d1,d0
  2213.         movea.l    (a0)+,a1
  2214.         move.l    d0,trk_audioaddr(a1)
  2215.         add.l    d1,d0
  2216.         movea.l    (a0)+,a1
  2217.         move.l    d0,trk_audioaddr(a1)
  2218.         add.l    d1,d0
  2219.         movea.l    (a0)+,a1
  2220.         move.l    d0,trk_audioaddr(a1)
  2221.         lea    -32(a0),a0
  2222.         moveq    #7,d0
  2223. 2$        movea.l    (a0)+,a1
  2224.         st    trk_tempvol(a1)
  2225.         dbf    d0,2$
  2226.         rts
  2227.  
  2228.  
  2229.         DATA
  2230.         XDEF    _hq
  2231. DB:        ;Data base pointer
  2232.     IFNE    AUDDEV
  2233. sigbitnum    dc.b    -1
  2234. audiodevopen    dc.b    0
  2235. allocm        dc.b    $F,0
  2236.     ENDC
  2237. chdmamask    dc.w    0
  2238. trksplit    dc.b    0,0,0,0
  2239.         even
  2240.     IFNE    AUDDEV
  2241. allocport    dc.l    0,0    ;succ, pred
  2242.         dc.b    4,0    ;NT_MSGPORT
  2243.         dc.l    0    ;name
  2244.         dc.b    0,0    ;flags = PA_SIGNAL
  2245.         dc.l    0    ;task
  2246. reqlist        dc.l    0,0,0    ;list head, tail and tailpred
  2247.         dc.b    5,0
  2248. allocreq    dc.l    0,0
  2249.         dc.b    0,127    ;NT_UNKNOWN, use maximum priority (127)
  2250.         dc.l    0,allocport    ;name, replyport
  2251.         dc.w    68        ;length
  2252.         dc.l    0    ;io_Device
  2253.         dc.l    0    ;io_Unit
  2254.         dc.w    0    ;io_Command
  2255.         dc.b    0,0    ;io_Flags, io_Error
  2256.         dc.w    0    ;ioa_AllocKey
  2257.         dc.l    allocm    ;ioa_Data
  2258.         dc.l    1    ;ioa_Length
  2259.         dc.w    0,0,0    ;ioa_Period, Volume, Cycles
  2260.         dc.w    0,0,0,0,0,0,0,0,0,0    ;ioa_WriteMsg
  2261. audiodevname    dc.b    'audio.device',0
  2262.     ENDC
  2263.         even
  2264.  
  2265. zerodata    dc.w    0
  2266. whichbuff    dc.w    0
  2267.  
  2268. track0hw    dc.l    0,0,tmpvol,0,0
  2269.         dc.w    $0001,$df,$f0a0
  2270.         dc.l    0
  2271. track1hw    dc.l    0,0,tmpvol+1,0,0
  2272.         dc.w    $0002,$df,$f0b0
  2273.         dc.l    fmpstructs
  2274. track2hw    dc.l    0,0,tmpvol+2,0,0
  2275.         dc.w    $0004,$df,$f0c0
  2276.         dc.l    fmpstructs+fmp_sizeof
  2277. track3hw    dc.l    0,0,tmpvol+3,0,0
  2278.         dc.w    $0008,$df,$f0d0
  2279.         dc.l    fmpstructs+2*fmp_sizeof
  2280. track4hw    dc.l    0,0,tmpvol,0,0
  2281.         dc.w    0,0,0
  2282.         dc.l    0
  2283. track5hw    dc.l    0,0,tmpvol+1,0,0
  2284.         dc.w    0,0,0
  2285.         dc.l    0
  2286. track6hw    dc.l    0,0,tmpvol+2,0,0
  2287.         dc.w    0,0,0
  2288.         dc.l    0
  2289. track7hw    dc.l    0,0,tmpvol+3,0,0
  2290.         dc.w    0,0,0
  2291.         dc.l    0
  2292. SIZE4TRKHW    equ    4*$1E
  2293.  
  2294. tmpvol        dc.b    0,0,0,0
  2295.  
  2296. audintname    dc.b    'OctaMED AudioInterrupt',0
  2297.         even
  2298. audiointerrupt    dc.w    0,0,0,0,0
  2299.         dc.l    audintname,_audiobuff,_IntHandler8
  2300. prevaud        dc.l    0
  2301. play8        dc.b    0
  2302. eightrkon    dc.b    0
  2303. intonmsk    dc.w    0
  2304. dmaonmsk    dc.w    0
  2305.  
  2306. ; TRACK-data structures
  2307. t07d        ds.b    8*TRACKDATASZ
  2308.  
  2309. ; Build pointer table. This works on Devpac assembler, other assemblers
  2310. ; may need modifications.
  2311. trackdata8
  2312. TRKCOUNT    SET    0
  2313.         REPT    8
  2314.         dc.l    t07d+TRKCOUNT
  2315. TRKCOUNT    SET    TRKCOUNT+TRACKDATASZ
  2316.         ENDR
  2317.  
  2318. blkdelay    dc.w    0    ;block delay (PT PatternDelay)
  2319.  
  2320. eightchsizes    dc.b    110,120,130,140,150,160,170,180,190,200
  2321.         dc.b    101,110,119,128,137,146,156,165,174,183 ;HQ sizes
  2322. currchsize    dc.w    0    ;<< 3
  2323. currchsize2    dc.w    0
  2324. currchszcnt    dc.w    0
  2325.  
  2326. nextblock    dc.b    0 ;\ DON'T SEPARATE
  2327. nxtnoclrln    dc.b    0 ;/
  2328. numtracks    dc.w    0
  2329. numlines    dc.w    0
  2330. numpages    dc.w    0
  2331. nextblockline    dc.w    0
  2332. rptline        dc.w    0
  2333. rptcounter    dc.w    0
  2334. _module8    dc.l    0
  2335. fxplineblk    dc.l    0
  2336. _hq        dc.b    1
  2337.  
  2338.         EVEN
  2339.     IFNE    FASTMEMPLAY
  2340.         XDEF    _fastmemplay8,_fmp_buffsize8
  2341. _use_fastmem    dc.w    0
  2342. _fmp_buffsize8    dc.w    64    ;must be divisible by 4!
  2343. _fastmemplay8    dc.w    0
  2344. ; Fastmemplay interrupt structures
  2345. fmpintname    dc.b    'OctaMED FastMemPlay Int',0
  2346.         even
  2347. fmpinterrupt1    dc.w    0,0,0,0,0
  2348.         dc.l    fmpintname,fmpstructs,_FmpIntHandler
  2349. fmpinterrupt2    dc.w    0,0,0,0,0
  2350.         dc.l    fmpintname,fmpstructs+fmp_sizeof,_FmpIntHandler
  2351. fmpinterrupt3    dc.w    0,0,0,0,0
  2352.         dc.l    fmpintname,fmpstructs+2*fmp_sizeof,_FmpIntHandler
  2353.     ENDC
  2354.  
  2355. holdvals    ds.b    63
  2356. finetunes    ds.b    63
  2357. flags        ds.b    63
  2358.         EVEN
  2359.  
  2360.     IFNE    IFFMOCT
  2361.     dc.w    3424,3232,3048,2880,2712,2560,2416,2280,2152,2032,1920,1812
  2362.     dc.w    1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906
  2363.     ENDC
  2364. per0    dc.w    856,808,762,720,678,640,604,570,538,508,480,453
  2365.     dc.w    428,404,381,360,339,320,302,285,269,254,240,226
  2366.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2367.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2368.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2369.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2370.     IFNE    IFFMOCT
  2371.     dc.w    3400,3209,3029,2859,2699,2547,2404,2269,2142,2022,1908,1801
  2372.     dc.w    1700,1605,1515,1430,1349,1274,1202,1135,1071,1011,954,901
  2373.     ENDC
  2374. per1    dc.w    850,802,757,715,674,637,601,567,535,505,477,450
  2375.     dc.w    425,401,379,357,337,318,300,284,268,253,239,225
  2376.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2377.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2378.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2379.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2380.     IFNE    IFFMOCT
  2381.     dc.w    3376,3187,3008,2839,2680,2529,2387,2253,2127,2007,1895,1788
  2382.     dc.w    1688,1593,1504,1419,1340,1265,1194,1127,1063,1004,947,894
  2383.     ENDC
  2384. per2    dc.w    844,796,752,709,670,632,597,563,532,502,474,447
  2385.     dc.w    422,398,376,355,335,316,298,282,266,251,237,224
  2386.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2387.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2388.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2389.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2390.     IFNE    IFFMOCT
  2391.     dc.w    3352,3164,2986,2819,2660,2511,2370,2237,2112,1993,1881,1776
  2392.     dc.w    1676,1582,1493,1409,1330,1256,1185,1119,1056,997,941,888
  2393.     ENDC
  2394. per3    dc.w    838,791,746,704,665,628,592,559,528,498,470,444
  2395.     dc.w    419,395,373,352,332,314,296,280,264,249,235,222
  2396.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2397.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2398.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2399.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2400.     IFNE    IFFMOCT
  2401.     dc.w    3328,3141,2965,2799,2641,2493,2353,2221,2097,1979,1868,1763
  2402.     dc.w    1664,1571,1482,1399,1321,1247,1177,1111,1048,989,934,881
  2403.     ENDC
  2404. per4    dc.w    832,785,741,699,660,623,588,555,524,495,467,441
  2405.     dc.w    416,392,370,350,330,312,294,278,262,247,233,220
  2406.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2407.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2408.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2409.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2410.     IFNE    IFFMOCT
  2411.     dc.w    3304,3119,2944,2778,2622,2475,2336,2205,2081,1965,1854,1750
  2412.     dc.w    1652,1559,1472,1389,1311,1238,1168,1103,1041,982,927,875
  2413.     ENDC
  2414. per5    dc.w    826,779,736,694,655,619,584,551,520,491,463,437
  2415.     dc.w    413,390,368,347,328,309,292,276,260,245,232,219
  2416.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2417.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2418.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2419.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2420.     IFNE    IFFMOCT
  2421.     dc.w    3280,3096,2922,2758,2603,2457,2319,2189,2066,1950,1841,1738
  2422.     dc.w    1640,1548,1461,1379,1302,1229,1160,1095,1033,975,920,869
  2423.     ENDC
  2424. per6    dc.w    820,774,730,689,651,614,580,547,516,487,460,434
  2425.     dc.w    410,387,365,345,325,307,290,274,258,244,230,217
  2426.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2427.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2428.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2429.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2430.     IFNE    IFFMOCT
  2431.     dc.w    3256,3073,2901,2738,2584,2439,2302,2173,2051,1936,1827,1725
  2432.     dc.w    1628,1537,1450,1369,1292,1220,1151,1087,1026,968,914,862
  2433.     ENDC
  2434. per7    dc.w    814,768,725,684,646,610,575,543,513,484,457,431
  2435.     dc.w    407,384,363,342,323,305,288,272,256,242,228,216
  2436.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2437.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2438.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2439.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2440.     IFNE    IFFMOCT
  2441.     dc.w    3628,3424,3232,3051,2880,2718,2565,2421,2285,2157,2036,1922
  2442.     dc.w    1814,1712,1616,1525,1440,1359,1283,1211,1143,1079,1018,961
  2443.     ENDC
  2444. per_8    dc.w    907,856,808,762,720,678,640,604,570,538,508,480
  2445.     dc.w    453,428,404,381,360,339,320,302,285,269,254,240
  2446.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2447.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2448.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2449.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2450.     IFNE    IFFMOCT
  2451.     dc.w    3588,3387,3197,3017,2848,2688,2537,2395,2260,2133,2014,1901
  2452.     dc.w    1794,1693,1598,1509,1424,1344,1269,1197,1130,1067,1007,950
  2453.     ENDC
  2454. per_7    dc.w    900,850,802,757,715,675,636,601,567,535,505,477
  2455.     dc.w    450,425,401,379,357,337,318,300,284,268,253,238
  2456.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2457.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2458.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2459.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2460.     IFNE    IFFMOCT
  2461.     dc.w    3576,3375,3186,3007,2838,2679,2529,2387,2253,2126,2007,1894
  2462.     dc.w    1788,1688,1593,1504,1419,1339,1264,1193,1126,1063,1003,947
  2463.     ENDC
  2464. per_6    dc.w    894,844,796,752,709,670,632,597,563,532,502,474
  2465.     dc.w    447,422,398,376,355,335,316,298,282,266,251,237
  2466.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2467.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2468.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2469.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2470.     IFNE    IFFMOCT
  2471.     dc.w    3548,3349,3161,2984,2816,2658,2509,2368,2235,2110,1991,1879
  2472.     dc.w    1774,1674,1580,1492,1408,1329,1254,1184,1118,1055,996,940
  2473.     ENDC
  2474. per_5    dc.w    887,838,791,746,704,665,628,592,559,528,498,470
  2475.     dc.w    444,419,395,373,352,332,314,296,280,264,249,235
  2476.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2477.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2478.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2479.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2480.     IFNE    IFFMOCT
  2481.     dc.w    3524,3326,3140,2963,2797,2640,2492,2352,2220,2095,1978,1867
  2482.     dc.w    1762,1663,1570,1482,1399,1320,1246,1176,1110,1048,989,933
  2483.     ENDC
  2484. per_4    dc.w    881,832,785,741,699,660,623,588,555,524,494,467
  2485.     dc.w    441,416,392,370,350,330,312,294,278,262,247,233
  2486.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2487.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2488.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2489.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2490.     IFNE    IFFMOCT
  2491.     dc.w    3500,3304,3118,2943,2778,2622,2475,2336,2205,2081,1964,1854
  2492.     dc.w    1750,1652,1559,1472,1389,1311,1237,1168,1102,1041,982,927
  2493.     ENDC
  2494. per_3    dc.w    875,826,779,736,694,655,619,584,551,520,491,463
  2495.     dc.w    437,413,390,368,347,328,309,292,276,260,245,232
  2496.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2497.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2498.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2499.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2500.     IFNE    IFFMOCT
  2501.     dc.w    3472,3277,3093,2920,2756,2601,2455,2317,2187,2064,1949,1839
  2502.     dc.w    1736,1639,1547,1460,1378,1301,1228,1159,1094,1032,974,920
  2503.     ENDC
  2504. per_2    dc.w    868,820,774,730,689,651,614,580,547,516,487,460
  2505.     dc.w    434,410,387,365,345,325,307,290,274,258,244,230
  2506.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2507.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2508.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2509.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2510.     IFNE    IFFMOCT
  2511.     dc.w    3448,3254,3072,2899,2737,2583,2438,2301,2172,2050,1935,1827
  2512.     dc.w    1724,1627,1536,1450,1368,1292,1219,1151,1086,1025,968,913
  2513.     ENDC
  2514. per_1    dc.w    862,814,768,725,684,646,610,575,543,513,484,457
  2515.     dc.w    431,407,384,363,342,323,305,288,272,256,242,228
  2516.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2517.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2518.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2519.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2520.  
  2521. _periodtable
  2522.     dc.l    per_8,per_7,per_6,per_5,per_4,per_3,per_2,per_1,per0
  2523.     dc.l    per1,per2,per3,per4,per5,per6,per7
  2524.  
  2525.     IFND    __G2
  2526.         section "datachip",bss,chip ;for A68k
  2527.     ENDC
  2528.     IFD    __G2
  2529.         section "datachip",bss_c ;this is for Devpac 2
  2530.     ENDC
  2531.  
  2532.         XDEF    _modnum8
  2533. _audiobuff:    ds.w    400*8
  2534. _fmpaudiobuff    ds.w    2400
  2535.     IFNE    FASTMEMPLAY
  2536.     ENDC
  2537. _modnum8:    ds.w    1
  2538. _chipzero:    ds.w    1
  2539.  
  2540.     IFNE    FASTMEMPLAY
  2541.         BSS
  2542. fmpstructs    ds.b    fmp_sizeof*3
  2543.     ENDC
  2544.  
  2545.         END
  2546.